Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/83.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从T-SQL中的频率列创建修改的行_Sql_Sql Server - Fatal编程技术网

从T-SQL中的频率列创建修改的行

从T-SQL中的频率列创建修改的行,sql,sql-server,Sql,Sql Server,我需要一些关于在SQL上为频率列的每个计数创建行的有效方法的想法。(SQL Server 2016) 数据: 我有一张桌子,上面写着人们请病假的日期和他们说要缺席多少天: BEGIN_DATE DAYS_SICK 2011-01-01 00:00:00.000 3 2011-01-01 00:00:00.000 3 2011-01-01 00:00:00.000 1 2011-01-02 00:00:00.000 2 2011-01-02 00:00:00.0

我需要一些关于在SQL上为频率列的每个计数创建行的有效方法的想法。(SQL Server 2016)

数据:
我有一张桌子,上面写着人们请病假的日期和他们说要缺席多少天:

BEGIN_DATE               DAYS_SICK
2011-01-01 00:00:00.000  3
2011-01-01 00:00:00.000  3
2011-01-01 00:00:00.000  1
2011-01-02 00:00:00.000  2
2011-01-02 00:00:00.000  3
2011-01-04 00:00:00.000  4
2011-01-04 00:00:00.000  4
2011-01-04 00:00:00.000  3
我想把它转换成一个表格,其中每一行代表一年中的一天,我计算那天生病的人数

DATE                     PEOPLE_SICK
2011-01-01 00:00:00.000  3 
2011-01-02 00:00:00.000  4
2011-01-03 00:00:00.000  4
2011-01-04 00:00:00.000  4
2011-01-05 00:00:00.000  3
2011-01-06 00:00:00.000  3
2011-01-07 00:00:00.000  2
例如:

  • 2011年1月1日,共有3人请了病假,2人请了3天病假,1人只请了当天的病假。输出为3
  • 现在在2011-01-02,另外两个(不同的)人打电话请病假,但前一天有两个人说他们也会错过那一天,所以输出是4
  • 2011-01-03没有人打电话请病假,但两天前有两个人说他们将错过那一天,加上前一天的两个人。输出为4
  • 等等
我目前正在通过迭代输入中的每一行,然后循环频率,根据需要在新表中添加或更新行来实现这一点,但这需要花费大量的时间


还有其他更有效的方法吗?

这根本不涉及周末,但可以让你开始。另外,如果有一个经常运行的查询,我会构建一个日期DIM表,并使用它来代替日期CTE

CREATE TABLE #test (ID int IDENTITY(1,1), BEGIN_DATE datetime, DAYS_SICK int);

DECLARE @StartDate datetime = '2011-01-01'
, @CutoffDate datetime = '2011-01-10';

INSERT INTO #test (BEGIN_DATE, DAYS_SICK)
VALUES 
('2011-01-01 00:00:00.000',  3),
('2011-01-01 00:00:00.000',  3),
('2011-01-01 00:00:00.000',  1),
('2011-01-02 00:00:00.000',  2),
('2011-01-02 00:00:00.000',  3),
('2011-01-04 00:00:00.000',  4),
('2011-01-04 00:00:00.000',  4),
('2011-01-04 00:00:00.000',  3);

WITH Dates
AS (SELECT d
    FROM (
        SELECT d = DATEADD(DAY, rn - 1, @StartDate)
        FROM (SELECT TOP (DATEDIFF(DAY, @StartDate, @CutoffDate)) rn = ROW_NUMBER() OVER (
                    ORDER BY s1.[object_id])
            FROM sys.all_objects AS s1
            CROSS JOIN sys.all_objects AS s2
            ORDER BY s1.[object_id]
            ) AS x
        ) AS y
    )
    ,SickRanges
AS (
    SELECT BEGIN_DATE
        ,DATEADD(DAY, DAYS_SICK - 1, BEGIN_DATE) END_DATE
    FROM #test
    )
SELECT d.d [DATE]
    ,count(1) PEOPLE_SICK
FROM SickRanges sr
JOIN Dates d ON d.d BETWEEN sr.BEGIN_DATE AND sr.END_DATE
GROUP BY d.d
ORDER BY d.d

DROP TABLE #test