在滚动的12个月内计算病期和持续时间

时间:2015-08-05 08:16:30

标签: sql-server sql-server-2008 tsql

我对SQL很新,发现这个网站是一个很棒的资源。我希望能为我分配的任务提供一些帮助。

基本上我需要找出一名工作人员在过去12个月内服用的病假次数以及每个病期的持续时间。

我有一个简单的表格,如下所示:

Agent Date       Status
A     01/07/2015 SHIFT
A     02/07/2015 SHIFT
A     03/07/2015 SICK
A     04/07/2015 SHIFT
A     05/07/2015 SHIFT
A     06/07/2015 SHIFT
B     01/07/2015 SICK
B     02/07/2015 SICK
B     03/07/2015 SHIFT
B     04/07/2015 SHIFT
B     05/07/2015 SICK
B     06/07/2015 SICK
C     01/07/2015 SHIFT
C     02/07/2015 SHIFT
C     03/07/2015 SICK
C     04/07/2015 SICK
C     05/07/2015 SICK
C     06/07/2015 SHIFT

我希望有人可以帮我找到一些可以产生以下输出的代码:

Agent   Days
A       1
B       2
B       2
C       3

非常感谢任何帮助。

干杯

1 个答案:

答案 0 :(得分:2)

对于sql-server:

select count(1) from TableA
  where Status = 'SICK' and Date >= CAST(DATEADD(MONTH, -12, CURRENT_TIMESTAMP) AS DATE)
  group by Agent

由疾病时期组成:

WITH Cte AS(
    SELECT *,
        DATEDIFF(dd, '12/30/1899', [Date]) as [number],
        RN = DATEDIFF(dd, '12/30/1899', [Date]) - ROW_NUMBER()
     OVER(PARTITION BY Agent ORDER BY DATEDIFF(dd, '12/30/1899', [Date]))
    FROM TableA 
     WHERE  
        [Status] = 'SICK' and 
        [Date] >= CAST(DATEADD(MONTH, -12, CURRENT_TIMESTAMP) AS DATE)
)
,CteFinal AS(
    SELECT
        Agent,
    startNumber = MIN(number),
    endNumber = MAX(number)
FROM Cte
GROUP BY Agent, RN
)

select Agent, endNumber - startNumber +1 as [Days] from CteFinal
group by agent, startNumber, endNumber

Sqlfiddle

此外,对于表格B中的休假情况:

WITH Cte AS(
    SELECT distinct *,
        DATEDIFF(dd, '12/30/1899', [Date]) as [number],
        RN = DATEDIFF(dd, '12/30/1899', [Date]) - ROW_NUMBER()
     OVER(PARTITION BY Agent ORDER BY DATEDIFF(dd, '12/30/1899', [Date]))
    FROM (select distinct * from TableA 
        union all 
        select distinct Agent, b.Date, 'DAY OFF' from TableA cross join TableB b) TableA 
     WHERE  
        [Status] IN ('SICK', 'DAY OFF') and 
        [Date] >= CAST(DATEADD(MONTH, -12, CURRENT_TIMESTAMP) AS DATE)
)
,CteFinal AS(
    SELECT
        Agent,
    startNumber = MIN(number),
    endNumber = MAX(number),
    dayOffs = SUM(CASE WHEN [Status] = 'DAY OFF' THEN 1 ELSE 0 END)
FROM Cte
GROUP BY Agent, RN
)

select Agent, endNumber - startNumber +1 - sum(dayOffs) as [Days] from CteFinal
group by agent, startNumber, endNumber
having(endNumber - startNumber +1 - sum(dayOffs) > 0)

Sqlfiddle