对于两个日期之间的每一天,添加一行,其中包含相同的信息但仅在开始/结束列中的那一天

Jus*_*ner 9 sql sql-server datetime insert

我有一个表,与类型varchar,datetime,datetime:

NAME | START | END
Bob  | 10/30 | 11/2
Run Code Online (Sandbox Code Playgroud)

我可以查看什么是SQL查询以了解如何使该表成为?:

NAME | START | END
Bob  | 10/30 | 10/30
Bob  | 10/31 | 10/31
Bob  | 11/01 | 11/01
Bob  | 11/02 | 11/02
Run Code Online (Sandbox Code Playgroud)

这只运行一次,并且在一个非常小的数据集上运行.优化不是必需的.

Pரத*_*ீப் 10

可能你需要一个Recursive CTE.

CREATE TABLE #dates(NAME  VARCHAR(50),START DATETIME,[END] DATETIME)

INSERT INTO #dates
VALUES      ('Bob','2014-10-30','2014-11-02')

DECLARE @maxdate DATETIME = (SELECT Max([end]) FROM   #dates);

WITH cte
     AS (SELECT NAME,
                START,
                [END]
         FROM   #dates
         UNION ALL
         SELECT NAME,
                Dateadd(day, 1, start),
                Dateadd(day, 1, start)
         FROM   cte
         WHERE  start < @maxdate)
SELECT *
FROM   cte 
Run Code Online (Sandbox Code Playgroud)

输出:

name    START       END
----    ----------  ----------
Bob     2014-10-30  2014-10-30
Bob     2014-10-31  2014-10-31
Bob     2014-11-01  2014-11-01
Bob     2014-11-02  2014-11-02
Run Code Online (Sandbox Code Playgroud)


Har*_* CO 10

您可以使用递归cte执行此操作:

;with cte AS (SELECT Name,Start,[End]
              FROM YourTable
              UNION  ALL
              SELECT Name
                    ,DATEADD(day,1,Start)
                    ,[End]
              FROM cte
              WHERE Start < [End])
SELECT Name, Start, Start AS [End]
FROM cte
Run Code Online (Sandbox Code Playgroud)

但是,我建议创建一个日历表并加入它:

SELECT a.Name,b.CalendarDate AS Start, b.CalendarDate AS [End]
FROM YourTable a
JOIN tlkp_Calendar b
  ON b.CalendarDate BETWEEN a.[Start] AND a.[End]
Run Code Online (Sandbox Code Playgroud)

演示两个查询:SQL Fiddle


She*_*ets 6

我对这个问题/答案的问题是它仅适用于一条记录。我在这篇回答帖子中找到了一个简单而有效的解决方案 - SQL how to conversion row with date range to many rows with every date

\n\n

“RichardTheKiwi”的解决方案涉及基于整数表(列表)添加新的日期记录,并通过使用datediff函数评估日期范围来连接到源表。您可以直接从 SQL Server 主数据库 ( ) 中提取整数列表SELECT master..spt_values WHERE v.type=\'P\'。这

\n\n

谷歌搜索词sql spt_values,有很多关于这个表的有趣的博客文章。例如...

\n\n\n\n

完整解决方案:

\n\n
--NAME | START | END\n--Bob  | 10/30 | 11/2\n\nDECLARE @SampleData as table \n    (PersonName nvarchar(50), StartDate date, EndDate date)\nINSERT INTO @SampleData\n    (PersonName, StartDate, EndDate)\nVALUES\n    (\'Bob\', \'2019-10-30\', \'2019-11-02\')\n    , (\'Joe\', \'2019-10-30\', \'2019-11-05\')\n;\n\nWITH \ncteSampleData_RecordAdded AS\n-- NOTE: Range record converted to daily records for \'SampleData\'\n(\n    SELECT \n        T1.PersonName\n        , T1.StartDate\n        , T1.EndDate\n        , DATEADD(d,v.number,T1.StartDate) AS [NewRecordDate]\n        , DATEDIFF(day, T1.StartDate, T1.EndDate)+1 AS [QDaysActive]\n    FROM \n        @SampleData T1\n        -- Adds a record for each date in the range\n        JOIN MASTER..spt_values v \n            ON v.type=\'P\'AND v.number BETWEEN 0 AND datediff(d, T1.StartDate, T1.EndDate)\n)\n\nselect * from cteSampleData_RecordAdded\n
Run Code Online (Sandbox Code Playgroud)\n\n

结果:

\n\n
+------------+------------+-----------+---------------+-------------+\n| PersonName | StartDate  | EndDate   | NewRecordDate | QDaysActive |\n+------------+------------+-----------+---------------+-------------+\n| Bob        | 10/30/2019 | 11/2/2019 | 10/30/2019    | 4           |\n+------------+------------+-----------+---------------+-------------+\n| Bob        | 10/30/2019 | 11/2/2019 | 10/31/2019    | 4           |\n+------------+------------+-----------+---------------+-------------+\n| Bob        | 10/30/2019 | 11/2/2019 | 11/1/2019     | 4           |\n+------------+------------+-----------+---------------+-------------+\n| Bob        | 10/30/2019 | 11/2/2019 | 11/2/2019     | 4           |\n+------------+------------+-----------+---------------+-------------+\n| Joe        | 10/30/2019 | 11/5/2019 | 10/30/2019    | 7           |\n+------------+------------+-----------+---------------+-------------+\n| Joe        | 10/30/2019 | 11/5/2019 | 10/31/2019    | 7           |\n+------------+------------+-----------+---------------+-------------+\n| Joe        | 10/30/2019 | 11/5/2019 | 11/1/2019     | 7           |\n+------------+------------+-----------+---------------+-------------+\n| Joe        | 10/30/2019 | 11/5/2019 | 11/2/2019     | 7           |\n+------------+------------+-----------+---------------+-------------+\n| Joe        | 10/30/2019 | 11/5/2019 | 11/3/2019     | 7           |\n+------------+------------+-----------+---------------+-------------+\n| Joe        | 10/30/2019 | 11/5/2019 | 11/4/2019     | 7           |\n+------------+------------+-----------+---------------+-------------+\n| Joe        | 10/30/2019 | 11/5/2019 | 11/5/2019     | 7           |\n+------------+------------+-----------+---------------+-------------+\n
Run Code Online (Sandbox Code Playgroud)\n