繁体   English   中英

连续计算SQL Server天数

[英]Counting Consecutive days SQL Server

我希望为每个人计算连续的一天咒语。

我的桌子:

CREATE TABLE Absence(
Date Date,
Code varchar(10),
Name varchar(10),
Type varchar(10)
);

INSERT INTO Absence (Date, Code, Name, Type)
VALUES ('01-10-18', 'S', 'Sam', 'Sick'),
('01-11-18','S', 'Sam', 'Sick'),
('01-12-18','S', 'Sam', 'Sick'),
('01-21-18','S', 'Sam', 'Sick'),
('01-26-18','S', 'Sam', 'Sick'),
('01-27-18','S', 'Sam', 'Sick'),
('02-12-18','S', 'Sam', 'Holiday'),
('02-13-18','S', 'Sam', 'Holiday'),
('02-18-18','S', 'Sam', 'Holiday'),
('02-25-18','S', 'Sam', 'Holiday'),
('02-10-18','S', 'Sam', 'Holiday'),
('02-13-18','F', 'Fred', 'Sick'),
('02-14-18','F', 'Fred', 'Sick'),
('02-17-18','F', 'Fred', 'Sick'),
('02-25-18','F', 'Fred', 'Sick'),
('02-28-18','F', 'Fred', 'Sick');

这是我目前拥有的代码:

WITH CTE AS
(
SELECT 
Date,
Name, 
Type
,GroupingSet = DATEADD(DAY, ROW_NUMBER() OVER 
(PARTITION BY [Name], [Type] ORDER BY [Date]), [Date])
FROM Absence
)
SELECT 
    Name,
    StartDate = MIN(Date),
    EndDate = MAX(Date),
    Result = COUNT(Name),
    min(Type) AS [Type]
    FROM CTE

   GROUP BY Name, GroupingSet
    -- HAVING COUNT(NULLIF(Code, 0)) > 1
   ORDER BY Name, StartDate

产生结果:

| Name |  StartDate |    EndDate | Result |    Type |
|------|------------|------------|--------|---------|
| Fred | 2018-02-13 | 2018-02-13 |      1 |    Sick |
| Fred | 2018-02-14 | 2018-02-14 |      1 |    Sick |
| Fred | 2018-02-17 | 2018-02-17 |      1 |    Sick |
| Fred | 2018-02-25 | 2018-02-25 |      1 |    Sick |
| Fred | 2018-02-26 | 2018-02-28 |      1 |    Sick |
|  Sam | 2018-01-10 | 2018-01-10 |      1 |    Sick |
|  Sam | 2018-01-11 | 2018-01-11 |      1 |    Sick |
|  Sam | 2018-01-12 | 2018-01-12 |      1 |    Sick |
|  Sam | 2018-01-21 | 2018-01-21 |      1 |    Sick |
|  Sam | 2018-01-26 | 2018-01-26 |      1 |    Sick |
|  Sam | 2018-01-27 | 2018-01-27 |      1 |    Sick |
|  Sam | 2018-02-10 | 2018-02-10 |      1 | Holiday |
|  Sam | 2018-02-12 | 2018-02-12 |      1 | Holiday |
|  Sam | 2018-02-13 | 2018-02-13 |      1 | Holiday |
|  Sam | 2018-02-18 | 2018-02-18 |      1 | Holiday |
|  Sam | 2018-02-25 | 2018-02-25 |      1 | Holiday |

在我正在寻找这样的结果集的地方:

| Name |       Date | Result  |    Type |
|------|------------|---------|---------|
| Fred | 2018-02-13 |       2 |    Sick |
|  Sam | 2018-01-27 |       2 |    Sick |
|  Sam | 2018-02-10 |       1 | Holiday |

我需要计算连续1天以上的连续天数。 然后将其作为某人拥有多少个连续咒语的总和。 例如,弗雷德在这段时间内连续2次生病。 如果某人有星期五和星期一休息,我也需要此内容,这应该算作连续咒语。

我对如何到达那里有些迷失。 任何帮助将不胜感激。

请参阅: http ://sqlfiddle.com/#!18/88612/16

您可以使用以下方式获取缺勤时间:

select name, min(date), max(date), count(*) as numdays, type
from (select a.*,
             row_number() over (partition by name, type order by date) as seqnum_ct
      from absence a
     ) a
group by name, type, dateadd(day, -seqnum_ct, date);

是一个SQL Fiddle。

您可以添加having count(*) > 1以获取一天或更长的期限。 这似乎很有用。 我不明白最终的输出是什么。 该描述对我而言毫无意义。

如果您希望缺勤的天数为2天或以上,则可以将其用作子查询/ CTE:

select name, count(*), type
from (select name, min(date) as mindate, max(date) as maxdate, count(*) as numdays, type
      from (select a.*,
                   row_number() over (partition by name, type order by date) as seqnum_ct
            from absence a
           ) a
      group by name, type, dateadd(day, -seqnum_ct, date)
     ) b
where numdays > 1
group by name, type;

尝试这个:

select name, min([date]) [date], count(*) [result], [type] from (
    select *, SUM(isConsecutive) over (partition by name,[type] order by [date] rows between unbounded preceding and current row) [isConsecutiiveId]
    from (
        select *, case when dateadd(day, -1, [date]) = LAG([date]) over (partition by name,[type] order by [date]) then 0 else 1 end [isConsecutive] from #Absence
    ) a
) a group by name,[type],isConsecutiiveId

它导致的缺勤期比您的预期结果长,因为在您的数据中有更多的缺勤期。 它显然包括您的结果,但还有更多:)

SELECT 
s.[Name], 'Last 12 Months' as [Date], s.[Type], COUNT(s.[numdays]) AS 
[Consecutive Spells]
FROM ( select name, min(date) AS [Date], max(date) AS [Date2], 
count(*) as numdays, type
from (select a.*, row_number() over (partition by name, type order by date) 
as seqnum_ct
  from absence a
 ) a
group by name, type, dateadd(day, -seqnum_ct, date)
HAVING count(*) > 1
)S
GROUP BY s.[Name], s.[Type]

这是我一直在寻找的结果。 -http://sqlfiddle.com/#!18/472d2/23

但是,感谢您对戈登的帮助,它使我朝着正确的方向前进!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM