如何检查时间差异

时间:2014-03-04 05:50:58

标签: sql sql-server tsql datetime

以下代码返回

CREATE TABLE #emp1 
  ( 
     empid   VARCHAR(50), 
     empname VARCHAR(50), 
     intime  SMALLDATETIME, 
     outtime SMALLDATETIME 
  ) 

INSERT INTO #emp1 
VALUES     (2500, 
            'Arun', 
            '2014-01-01 09:00:00', 
            '2014-01-01 10:30:0'), 
            (2500, 
             'Arun', 
             '2014-01-01 11:00:00:00', 
             '2014-01-01 11:00:0'), 
            (2500, 
             'Arun', 
             '2014-01-01 11:30:00:00', 
             '2014-01-01 19:00:00') 

SELECT empid, 
       Cast(intime AS DATE) 
       AS workingday, 
       empname, 
       RIGHT('0' + CONVERT(VARCHAR, Floor(Sum( Datediff( mi, intime, outtime)/ 
       60.0))), 
       2) 
       + ':' 
       + RIGHT('0' + CONVERT(VARCHAR, Sum( Datediff( mi, intime, outtime))%60), 
       2) AS 
       [total work_hour(s)], 
       CONVERT(VARCHAR(5), Max(outtime) - Min(intime), 108) 
       AS Difference, 
       Cast(Dateadd(minute, Sum(Datediff(mi, intime, outtime)) - 45, 0) AS TIME) 
       AS 
       TotalTime, 
       Cast(Dateadd(minute, CASE 
                              WHEN Sum(Datediff(mi, intime, outtime)) > 525 THEN 
                              Sum( 
                              Datediff(mi, intime, outtime)) - 525 
                              ELSE 0 
                            END, 0) AS TIME) 
       AS OverTime 
FROM   #emp1 
GROUP  BY empid, 
          empname, 
          Cast(intime AS DATE) 

DROP TABLE #emp1 
as



EmpId  workingday  EmpName  total work_hour(s)  Difference  TotalTime         OverTime
2500   2014-01-01  Arun     09:00               10:00       08:15:00.0000000  00:15:00.0000000

此处TotalTime为08:15,OverTime为00:15。一切都很好。

但是,我需要另一个字段ActualTime

即。如果TotalTime大于8小时,则ActualTimeTotalTimeOverTime的差异。在此示例中,ActualTime应为08:00。

如果TotalTime少于8小时,则ActualTimeTotalTime相同。

最后,我还想在TotalTimeOverTime

中避免多余的零

2 个答案:

答案 0 :(得分:1)

我想你想要这样的东西:* EDIT nullcheck添加

;with x as
(
SELECT empid, 
       Cast(intime AS DATE) workingday, 
       empname, 
       cast(dateadd(mi, sum(datediff(mi, 0, outtime - intime)), 0) as time) twh, 
       cast(dateadd(mi,datediff(mi,0,max(outtime)-min(intime)), 0) as time) Difference,
       case when count(outtime)=count(*) then '' end nullcheck
FROM #emp1 
GROUP BY empid, empname, Cast(intime AS DATE) 
)
select empid, workingday, empname, 
nullcheck+left(twh, 5) [total_hours], 
nullcheck+left(Difference, 5) Difference, 
nullcheck+left(cast(dateadd(mi, -45, twh)as time ),5) TotalTime,
nullcheck+left(case when twh > '08:45' then cast(dateadd(mi, -525, twh) as time) else '00:00' end, 5) OverTime,
nullcheck+left(case when twh > '08:00' then '08:00' else twh end, 5) actualtime
from x

结果:

empid workingday empname total_hours Difference TotalTime OverTime actualtime
2500  2014-01-01 Arun    09:00       10:00      08:15     00:15    08:00

答案 1 :(得分:0)

首先,我将整个当前查询包装在公用表表达式中,以便可以重用它的各个部分。

WITH CalculatedTime AS (SELECT empid, 
       Cast(intime AS DATE) AS workingday, 
       empname, 
       RIGHT('0' + CONVERT(VARCHAR, Floor(Sum( Datediff( mi, intime, outtime)/ 
       60.0))), 
       2) 
       + ':' 
       + RIGHT('0' + CONVERT(VARCHAR, Sum( Datediff( mi, intime, outtime))%60), 
       2) AS [total work_hour(s)], 
       CONVERT(VARCHAR(5), Max(outtime) - Min(intime), 108) 
       AS Difference, 
       Cast(Dateadd(minute, Sum(Datediff(mi, intime, outtime)) - 45, 0) AS TIME) 
       TotalTime, 
       Cast(Dateadd(minute, CASE 
                              WHEN Sum(Datediff(mi, intime, outtime)) > 525 THEN 
                              Sum( 
                              Datediff(mi, intime, outtime)) - 525 
                              ELSE 0 
                            END, 0) AS TIME) 
       OverTime 
FROM   #emp1 
GROUP  BY empid, 
          empname, 
          Cast(intime AS DATE) )

现在我们可以将CalculatedTime称为表格,我们不需要重复用于计算TotalTime列的任何讨厌逻辑。

所以最后一步是使用case语句来执行你想要的计算:

SELECT *,
    CASE WHEN DATEDIFF(minute,TotalTime,'08:00') > 0 THEN TotalTime
    ELSE DATEADD(minute, DATEDIFF(minute,OverTime, 0), TotalTime)
    END AS ActualTime
FROM CalculatedTime

问题的格式化部分(删除多余的零)是一个单独的问题,在StackOverflow之前已经多次回答。