运行 相对于 SQL 服务器中另一列的总数

Running total with respect to another column in SQL Server

我有一个 table,其中包含代表员工和他们工作日期的姓名和日期。我想创建 运行 他们工作的总天数,如果连续性中断,那么我想记下他们回来工作之前的中断时间。

这是实际数据:

+------+---------------------+
| Name |        Date         |
+------+---------------------+
| Adam | 01/01/2018 00:00:00 |
| Adam | 02/01/2018 00:00:00 |
| Adam | 03/01/2018 00:00:00 |
| Adam | 15/01/2018 00:00:00 |
| Ben  | 02/01/2018 00:00:00 |
| Ben  | 03/01/2018 00:00:00 |
+------+---------------------+

这是预期的结果:

+------+---------------------+------------------+---------+
| Name |        Date         | Consecutive_days | Holiday |
+------+---------------------+------------------+---------+
| Adam | 01/01/2018 00:00:00 |                1 |       0 |
| Adam | 02/01/2018 00:00:00 |                2 |       0 |
| Adam | 03/01/2018 00:00:00 |                3 |       0 |
| Adam | 15/01/2018 00:00:00 |                1 |      12 |
| Ben  | 02/01/2018 00:00:00 |                1 |       0 |
| Ben  | 03/01/2018 00:00:00 |                2 |       0 |
+------+---------------------+------------------+---------+

我知道我应该使用 SUM() OVER(ORDER BY Date) 子句,一旦我在连续几天之间有差异,但我很难弄清楚如何获得这些差异。

我想你想要这样的东西

CREATE TABLE T
    ([Name] varchar(4), [Date] datetime, [Consecutive_days] int);

INSERT INTO T
    ([Name], [Date], [Consecutive_days])
VALUES
    ('Adam', '2018-01-01 00:00:00', 1),
    ('Adam', '2018-01-02 00:00:00', 2),
    ('Adam', '2018-01-03 00:00:00', 3),
    ('Adam', '2018-01-15 00:00:00', 1),
    ('Ben', '2018-01-02 00:00:00', 1),
    ('Ben', '2018-01-03 00:00:00', 2);

WITH C AS
(
SELECT *,
       LAG([Date], 1, 0) OVER(ORDER BY [Date]) L
FROM T
)
SELECT Name,
       [Date],
       Consecutive_days,
       CASE WHEN DATEDIFF(Day, L, [Date]) > 1
                 AND
                 DATEDIFF(Day, L, [Date]) < 360
                 THEN
            DATEDIFF(Day, L, [Date])
            ELSE
            0 END Holiday

FROM C
ORDER BY Name;

Returns:

+------+---------------------+------------------+---------+
| Name |        Date         | Consecutive_days | Holiday |
+------+---------------------+------------------+---------+
| Adam | 01/01/2018 00:00:00 |                1 |       0 |
| Adam | 02/01/2018 00:00:00 |                2 |       0 |
| Adam | 03/01/2018 00:00:00 |                3 |       0 |
| Adam | 15/01/2018 00:00:00 |                1 |      12 |
| Ben  | 02/01/2018 00:00:00 |                1 |       0 |
| Ben  | 03/01/2018 00:00:00 |                2 |       0 |
+------+---------------------+------------------+---------+

create running total of days they were working and if there is a break in continuity then I would like to note how long the break was before they came back to work

你可以这样做

SELECT Name + ' has works ' + CAST(SUM(Consecutive_days) AS VARCHAR(10))+
                ' days, and '+
                CAST(SUM(Holiday) AS VARCHAR(10))+
                ' holidays' Result
FROM T
GROUP BY Name;

Returns:

+----------------------------------------+
|                 Result                 |
+----------------------------------------+
| Adam has works 7 days, and 12 holidays |
| Ben has works 3 days, and 0 holidays   |
+----------------------------------------+

根据您的更新

CREATE TABLE T
    ([Name] varchar(4), [Date] datetime);

INSERT INTO T
    ([Name], [Date])
VALUES
    ('Adam', '2018-01-01 00:00:00'),
    ('Adam', '2018-01-02 00:00:00'),
    ('Adam', '2018-01-03 00:00:00'),
    ('Adam', '2018-01-15 00:00:00'),
    ('Ben', '2018-01-02 00:00:00'),
    ('Ben', '2018-01-03 00:00:00');

SELECT T1.*,
       CASE WHEN
                 DATEDIFF(Day, X.[Date], T1.[Date]) > 1 THEN 1 
            ELSE
                 ROW_NUMBER() OVER (PARTITION BY Name ORDER BY Name)
            END Consecutive_days,
       CASE WHEN DATEDIFF(Day, X.[Date], T1.[Date]) IS NULL
                 OR
                 DATEDIFF(Day, X.[Date], T1.[Date]) = 1
                 THEN 0
                 ELSE
                 DATEDIFF(Day, X.[Date], T1.[Date])
                 END

FROM T T1 OUTER APPLY
(
SELECT TOP 1 [Date] 
FROM T T2 
WHERE T2.[Date] < T1.[Date] 
ORDER BY T2.[Date] DESC
) X;

Returns:

+------+---------------------+------------------+---------+
| Name |        Date         | Consecutive_days | Holiday |
+------+---------------------+------------------+---------+
| Adam | 01/01/2018 00:00:00 |                1 |       0 |
| Adam | 02/01/2018 00:00:00 |                2 |       0 |
| Adam | 03/01/2018 00:00:00 |                3 |       0 |
| Adam | 15/01/2018 00:00:00 |                1 |      12 |
| Ben  | 02/01/2018 00:00:00 |                1 |       0 |
| Ben  | 03/01/2018 00:00:00 |                2 |       0 |
+------+---------------------+------------------+---------+