sql开始和停止时间戳内的持续时间

时间:2015-11-03 20:11:13

标签: sql sql-server tsql

是否可以根据一秒钟内的一个时间戳(开始,停止)的分钟数来计算持续时间?

这就是我想要做的事情..返回员工在加班期间生病的分钟数。记录分段......病假例外可能并不总是在加班时间内。

所有行都在同一个表exceptions内。

Employee Exception  Start   Stop
Bob      OverTime   09:00   17:00
Jim      OverTime   14:00   16:00
Mark     OverTime   14:00   18:00
Steve    OverTime   10:00   14:00

Employee  Exception  Start  Stop 
Bob      Sick        09:00  09:30
Bob      Sick        14:00  17:00
Jim      Sick        14:00  16:00

结果:

Bob: 3.5 hours
Jim: 2 hours

2 个答案:

答案 0 :(得分:3)

SELECT 
    Employee,
    SUM(
        DATEDIFF(minute,
            (CASE WHEN SickStart > OvertimeStart THEN SickStart ELSE OvertimeStart END),
            (CASE WHEN SickStop > OvertimeStop THEN OvertimeStop ELSE SickStop END)
    )) / 60.0 [hours]
FROM (  
    SELECT e1.Employee, e1.START SickStart, e1.STOP SickStop,
           e2.START OvertimeStart, e2.STOP OvertimeStop 
    FROM   Exceptions e1
    JOIN   Exceptions e2 ON e1.Employee = e2.Employee
                AND (e1.START BETWEEN e2.START AND e2.STOP 
                OR e1.STOP BETWEEN e2.START AND e2.STOP)
    WHERE  e1.EXCEPTION = 'Sick'
           AND e2.EXCEPTION = 'OverTime'
) AS t
GROUP BY Employee;

答案 1 :(得分:2)

Sql Fiddle Demo

SELECT O.Employee, 
        CAST(CAST(
                DATEDIFF (
                           minute,
                           CASE WHEN S.Start < O.Start THEN O.Start
                                ELSE S.Start
                           END, 
                           CASE WHEN S.Stop > O.Stop THEN O.Stop
                                ELSE S.Stop
                           END
                         ) * 1.0 / 60 AS decimal (8,1)) as VARCHAR) + ' hours' as hours
 FROM exceptions O  -- Overtime
 JOIN exceptions S  -- Sick
   ON O.Employee = S.Employee 
  AND S.[Start] <= O.[Stop]
  AND S.[Stop] >= O.[Start]  
 WHERE 
      O.Exception  = 'OverTime'
  AND S.Exception  = 'Sick'

注意:

  • 我没有包含sum / group by,因此,如果这是您需要的价值,请先测试
  • 选中Determine Whether Two Date Ranges Overlap
  • 要测试Overtime以外的范围,我添加
    • ('Bob', 'Sick', '5:00', '7:00')未显示
    • ('Bob', 'Sick', '7:00', '10:00')仅显示1小时

<强>输出

| Employee |     hours |
|----------|-----------|
|      Bob | 0.5 hours |
|      Bob | 1.0 hours |
|      Bob | 3.0 hours |
|      Jim | 2.0 hours |

EDIT 我使用SUM

添加版本
 SELECT O.Employee, 
        CAST(CAST(
                SUM(DATEDIFF (
                           minute,
                           CASE WHEN S.Start < O.Start THEN O.Start
                                ELSE S.Start
                           END, 
                           CASE WHEN S.Stop > O.Stop THEN O.Stop
                                ELSE S.Stop
                           END
                         ) * 1.0 / 60) AS decimal (8,1)) as VARCHAR) + ' hours' as hours
 FROM exceptions O  -- Overtime
 JOIN exceptions S  -- Sick
   ON O.Employee = S.Employee 
  AND S.[Start] <= O.[Stop]
  AND S.[Stop] >= O.[Start]  
 WHERE 
      O.Exception  = 'OverTime'
  AND S.Exception  = 'Sick'
 GROUP BY O.Employee