【问题标题】:MS SQL SERVER LAGMS SQL 服务器滞后
【发布时间】:2018-12-28 14:21:32
【问题描述】:

我正在尝试在 SQL 查询中对LAG 应用条件。有谁知道如何做到这一点?

这是查询:

  SELECT CONCAT([FirstName],' ',[LastName]) AS employee,
         CAST([ArrivalTime] AS DATE) AS date,
         CAST(DATEADD(hour,2,FORMAT([ArrivalTime],'HH:mm')) AS TIME) as time,
         CASE [EventType]
         WHEN 20001 THEN 'ENTRY'
         ELSE 'EXIT'
         END AS Action,
         OutTime = 
  CASE [EventType]
  WHEN '20001'
  THEN DATEDIFF(minute,Lag([ArrivalTime],1) OVER(ORDER BY [CardHolderID], [ArrivalTime]), [ArrivalTime]) 
  ELSE
  NULL
  END
  FROM [CCFTEvent].[dbo].[ReportEvent]
  LEFT JOIN [CCFTCentral].[dbo].[Cardholder] ON  [CCFTEvent].[dbo].[ReportEvent].[CardholderID] = [CCFTCentral].[dbo].[Cardholder].[FTItemID]
  WHERE EventClass = 41
  AND [FirstName] IS NOT NULL
  AND [FirstName] LIKE 'Leeann%'

我遇到的问题是,当两个不同日期之间的时间相减时,两个不同日期之间的相减时间也必须是NULL

910 不正确。

【问题讨论】:

  • 您的两张图片看起来都像查询结果。如果您显示您的源数据会更有帮助。
  • 你不需要[FirstName] IS NOT NULL[FirstName] LIKE 'Leeann%'。如果FirstNameLIKE 'Leeann%',那么它将自动是NOT NULL。此外,您应该指出变量来自哪些表。如果FirstName 来自Cardholder,那么您不妨将条件移至JOIN 并将其更改为INNER JOIN。此外,放置变量将有助于您将来更好地了解查询流程。
  • 您的输入是什么,您期望最终输出是什么?您的两张图片都显示相同的内容。我假设ArrivalTimedatetime 数据类型?什么版本的 SQL Server?
  • 是什么让 910 不正确? 917也不对吗?
  • 感谢您的回复。 910 是不正确的,因为它在两个不同的日期之间进行计算,当发生这种情况时,我希望它为 NULL。我正在尝试计算员工不在大楼内的总时间。

标签: sql sql-server case lead


【解决方案1】:

我会在您的 case 语句中添加另一个条件。即

...
CASE 
   WHEN [EventType] = '20001' AND DATEDIFF(DAY,[ArrivalTime],LAG([ArrivalTime]) over (ORDER BY [CardHolderID], [ArrivalTime])) > 0
   THEN NULL
   WHEN [EventType] = '20001'
   THEN DATEDIFF(minute,Lag([ArrivalTime],1) OVER(ORDER BY [CardHolderID], [ArrivalTime]), [ArrivalTime])
   ELSE NULL

【讨论】:

  • 会试一试。感谢您的回复!
【解决方案2】:

在我看来,LAG 只需要按日期进行分区(以及一些其他字段,以便更好地衡量)。

如果上一个日期在另一个分区中,
那么 LAG 将返回 NULL,
那么 datediff 将返回 NULL。

SELECT 
 CONCAT(holder.FirstName+' ', holder.LastName) AS employee,
 CAST(repev.ArrivalTime AS DATE) AS [date],
 CAST(SWITCHOFFSET(repev.ArrivalTime,'+02:00') AS TIME)  as [time],
 IIF(repev.EventType = 20001, 'ENTRY', 'EXIT') AS Action,
 (CASE WHEN repev.EventType = 20001
  THEN DATEDIFF(minute, LAG(repev.ArrivalTime) 
                        OVER (PARTITION BY repev.EventClass, repev.CardholderID, CAST(repev.ArrivalTime AS DATE) 
                              ORDER BY repev.ArrivalTime), repev.ArrivalTime)
  END) AS OutTime
FROM [CCFTEvent].[dbo].[ReportEvent] AS repev
LEFT JOIN [CCFTCentral].[dbo].[Cardholder] AS holder ON holder.FTItemID = repev.CardholderID
WHERE repev.EventClass = 41
  AND holder.FirstName LIKE 'Leeann%'

测试 dbfiddle here

【讨论】:

  • 让我试试这个,我还没用过partioning。感谢您的回复!
猜你喜欢
  • 2015-10-02
  • 1970-01-01
  • 1970-01-01
  • 2017-04-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-02
  • 2015-01-23
  • 1970-01-01
相关资源
最近更新 更多