【问题标题】:SQL View Query need time interval calculation between 2 datesSQL View Query需要计算2个日期之间的时间间隔
【发布时间】:2017-11-12 16:23:21
【问题描述】:

我有以下查看查询。在计算时间间隔时,如果签出是同一日期,则仅显示时间间隔。例如,如果我在 2017 年 11 月 12 日入住,那么我必须在 201 年 11 月 12 日相同的日期退房,以便计算时间间隔。

但是我想修改它,就像我在第二天(午夜 12:00 AM 之后)结账时一样,它还应该计算时间间隔。可以帮我修改查询以获得所需的结果吗?

查询:

ALTER VIEW [dbo].[TimeAttendanceQuery]
AS
SELECT TOP (100)    PERCENT 
    dbo.AxPerson.Name,
    dbo.AxPerson.IdNumber  AS EmployeeID,
    dbo.TimeAttendance.Badge, 
    dbo.AxPerson.Id, 
    MIN(dbo.TimeAttendance.EventTime) AS EntryTime, 

    MAX(dbo.TimeAttendance.EventTime) AS ExitTime,
    CAST(DATEDIFF(second, MIN(dbo.TimeAttendance.EventTime), MAX(dbo.TimeAttendance.EventTime)) / 60 / 60 / 24 AS NVARCHAR(50)) +
    ':' + CAST(DATEDIFF(second, MIN(dbo.TimeAttendance.EventTime), MAX(dbo.TimeAttendance.EventTime)) / 60 / 60 % 24 AS NVARCHAR(50)) + ':' + CAST(DATEDIFF(second, MIN(dbo.TimeAttendance.EventTime),  MAX(dbo.TimeAttendance.EventTime)) / 60 % 60 AS NVARCHAR(50))
    AS TimeInterval, 
    dbo.TimeAttendance.Event, 
    dbo.AxPerson.Type AS ShitType, 
    dbo.AxPerson.ShiftDesc, 
    CONVERT(Varchar,dbo.TimeAttendance.EventTime, 101) AS EventTIME

FROM
    dbo.AxPerson 
INNER JOIN dbo.TimeAttendance ON dbo.AxPerson.Name = dbo.TimeAttendance.Name
GROUP BY  dbo.AxPerson.Name, dbo.AxPerson.IdNumber, dbo.TimeAttendance.Badge, CONVERT(Varchar, dbo.TimeAttendance.EventTime, 101), dbo.         AxPerson.ShiftDesc, dbo.AxPerson.Id, dbo.TimeAttendance.Event,dbo.AxPerson.Type
ORDER BY dbo.AxPerson.Name, EventTime DESC

GO

【问题讨论】:

  • 您有确定事件类型的列吗?是的,签到事件的值是多少,结帐事件的值是多少?
  • 删除TOP(100) PERCENTORDER BY,因为它们在视图定义中是多余的。您需要在使用视图的SELECT 语句中指定ORDER BY 以保证结果集排序。
  • 样本数据和期望的结果会有所帮助。
  • @DawoodAwan 是的,我确实有一列告诉事件是 entry r exit

标签: sql sql-server database sql-server-2008


【解决方案1】:

我不确定您发布的算法,但如果您想获得两个日期时间的时差,您可以将减法转换为时间。这工作不到 24 小时。如果您还想要天数(我认为这只适用于不到一年的时间),那么您可以做 datepart-day 的差异。

例如:

DECLARE @starttime datetime = '2017-11-12 010:20:00'
DECLARE @endtime   datetime = '2017-11-13 08:00:00'

SELECT DATEPART(DAY, @endtime - @starttime) - 1 [Days Passed]
      ,CAST(@endtime - @starttime as time(0)) [Time Passed]
       --WHERE the (0) in time(0) is for the milliseconds to return. 

给出输出:

Days Passed Time Passed
0           21:40:00

如果你不关心这些日子,那么你的代码可以这样修改:

ALTER VIEW [dbo].[TimeAttendanceQuery]
AS
SELECT Name, EmployeeID, Badge, Id, EntryTime,
       CAST(ExitTime - EntryTime as time(0)) [TimeInterval],
       Event, ShiftType, ShiftDesc
      ,CONVERT(Varchar, EventTime, 101) AS EventTIME
  FROM (
         SELECT
           dbo.AxPerson.Name,
           dbo.AxPerson.IdNumber  AS EmployeeID,
           dbo.TimeAttendance.Badge, 
           dbo.AxPerson.Id, 
           MIN(dbo.TimeAttendance.EventTime) AS EntryTime,  
           MAX(dbo.TimeAttendance.EventTime) AS ExitTime,             
           dbo.TimeAttendance.Event, 
           dbo.AxPerson.Type AS ShiftType, 
           dbo.AxPerson.ShiftDesc, 
           dbo.TimeAttendance.EventTime

           FROM dbo.AxPerson INNER JOIN dbo.TimeAttendance 
                                     ON dbo.AxPerson.Name = dbo.TimeAttendance.Name

           GROUP BY  
           dbo.AxPerson.Name, 
           dbo.AxPerson.IdNumber, 
           dbo.TimeAttendance.Badge, 
           dbo.AxPerson.Id, 
           dbo.TimeAttendance.Event,
           dbo.AxPerson.Type
           dbo.AxPerson.ShiftDesc,
           dbo.TimeAttendance.EventTime,
       ) AS dT

【讨论】:

  • 此算法仅适用于同一日期的签入和签出。我可以在入住后计算 24 小时时差。你能帮我在当前查询中更改什么吗?
猜你喜欢
  • 2020-04-11
  • 2010-11-08
  • 2010-09-17
  • 2013-03-25
  • 2012-03-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-18
相关资源
最近更新 更多