Sql server 多个“开始日期时间”和“结束日期时间”。为开始日期时间和结束日期时间之间的每个日期生成新行

Sql server 多个“开始日期时间”和“结束日期时间”。为开始日期时间和结束日期时间之间的每个日期生成新行,sql-server,datetime,Sql Server,Datetime,我正在使用SQLServer2008 我有一个包含许多列的表,其中包括“开始日期时间”和“开始日期时间”。因此,每行有一个“开始日期时间”和一个“结束日期时间”。 我需要为每行的“开始日期时间”和“结束日期时间”之间的每天生成一个新行。我将使用此表生成医院中占用的ICU病床的每日容量 我的表格中的示例数据: MRN |'Start datetime' |'End datetime' ----+-----------------+----------------------------------

我正在使用SQLServer2008

我有一个包含许多列的表,其中包括“开始日期时间”和“开始日期时间”。因此,每行有一个“开始日期时间”和一个“结束日期时间”。 我需要为每行的“开始日期时间”和“结束日期时间”之间的每天生成一个新行。我将使用此表生成医院中占用的ICU病床的每日容量

我的表格中的示例数据:

MRN |'Start datetime' |'End datetime'
----+-----------------+--------------------------------------    
007 | 1/1/2016        | 1/4/2016 --will return four rows
008 | 2/1/2015        | 2/3/2015 --will return three rows
期望输出:

Date       |MRN  |'Start datetime' |'End datetime'
-----------+-----+-----------------+---------------
01/01/2016 | 007 | 1/1/2016        | 1/4/2016
01/02/2016 | 007 | 1/1/2016        | 1/4/2016
01/03/2016 | 007 | 1/1/2016        | 1/4/2016
01/04/2016 | 007 | 1/1/2016        | 1/4/2016
02/01/2016 | 008 | 2/1/2015        | 2/3/2015
02/02/2016 | 008 | 2/1/2015        | 2/3/2015
02/03/2016 | 008 | 2/1/2015        | 2/3/2015
Date       |MRN  |'Start datetime' |'End datetime'
-----------+-----+-----------------+---------------
01/01/2016 | 007 | 1/1/2016        | 1/4/2016
01/02/2016 | 007 | 1/1/2016        | 1/4/2016
01/03/2016 | 007 | 1/1/2016        | 1/4/2016
01/04/2016 | 007 | 1/1/2016        | 1/4/2016
我试过游标和一些CTE,但我是SQL的新手,很容易被弄糊涂。理想情况下,该解决方案将允许我将现有查询粘贴到其主体中,而无需修改现有查询。我不喜欢使用drop tables,因为它最终会被输入tableau并每天更新

根据我的经验,桌上不能放桌子。谢谢你的帮助

谢谢@scsimon你的建议帮了大忙!唯一的问题是您的cte没有生成“所需输出”中的第一行,请参见下文

使用CTR输出:

Date       |MRN  |'Start datetime' |'End datetime'
-----------+-----+-----------------+---------------
01/02/2016 | 007 | 1/1/2016        | 1/4/2016
01/03/2016 | 007 | 1/1/2016        | 1/4/2016
01/04/2016 | 007 | 1/1/2016        | 1/4/2016
期望输出:

Date       |MRN  |'Start datetime' |'End datetime'
-----------+-----+-----------------+---------------
01/01/2016 | 007 | 1/1/2016        | 1/4/2016
01/02/2016 | 007 | 1/1/2016        | 1/4/2016
01/03/2016 | 007 | 1/1/2016        | 1/4/2016
01/04/2016 | 007 | 1/1/2016        | 1/4/2016
02/01/2016 | 008 | 2/1/2015        | 2/3/2015
02/02/2016 | 008 | 2/1/2015        | 2/3/2015
02/03/2016 | 008 | 2/1/2015        | 2/3/2015
Date       |MRN  |'Start datetime' |'End datetime'
-----------+-----+-----------------+---------------
01/01/2016 | 007 | 1/1/2016        | 1/4/2016
01/02/2016 | 007 | 1/1/2016        | 1/4/2016
01/03/2016 | 007 | 1/1/2016        | 1/4/2016
01/04/2016 | 007 | 1/1/2016        | 1/4/2016
你好,西蒙

以下是实际数据。再次感谢你的帮助。我实际上是在度假,所以我的网络是不稳定的,所以请原谅我迟来的回复。在查看数据时,我意识到我忽略了一点,即患者有可能在同一日期被转移两次,因此“开始日期时间”和“结束日期时间”是同一日期、不同时间。我相信这就是我问题的原因。”“开始日期时间”和“结束日期时间”为同一日期的所有行的“Mydate”在应等于该日期时等于NULL。请原谅我的格式化,格式化花了我这么长时间。谢谢你的帮助

我的数据:

MRN  |'Start datetime'|'End datetime'  
-------+--------------------------------+-----------------------  
0001 |2015-02-27 08:22:12.127 |2015-02-27 10:50:43.243  
0001 |2015-02-27 10:50:43.243 |2015-03-02 08:52:35.000  
0001 |2015-03-02 08:52:35.000 |2015-03-02 12:43:30.790  
0001 |2015-03-02 12:43:30.790 |2015-03-02 17:29:02.147 





My Output:

MyDate|MRN|'Start datetime'|'End datetime'  
-----------------------+---------+------------------+----------------------  
NULL                   |0001|2015-02-27 08:22:12.127|2015-02-27 10:50:43.243  
2015-02-28 00:00:00.000|0001|2015-02-27 10:50:43.243|2015-03-02 08:52:35.000  
2015-03-01 00:00:00.000|0001|2015-02-27 10:50:43.243|2015-03-02 08:52:35.000  
2015-03-02 00:00:00.000|0001|2015-02-27 10:50:43.243|2015-03-02 08:52:35.000  
NULL                   |0001|2015-03-02 08:52:35.000|2015-03-02 12:43:30.790  
NULL                   |0001|2015-03-02 12:43:30.790|2015-03-02 17:29:02.147 

假设数据库中有日期表


只需使用ON StartDate>=DateTable对该日期表进行内部联接。date和EndDate首先创建一个日期的CTE,然后联接到数据,为每个日期生成一行

--the #tempTable is used here for test. Replace #tempTable in your code with your actual table
if object_id('tempdb..#tempTable') is not null drop table #tempTable
create table #tempTable(
    MRN varchar(4),
    [Start datetime] datetime,
    [End datetime] datetime)

insert into #tempTable (MRN, [Start datetime], [End datetime]) VALUES
('0001','2015-02-27 08:22:12.127','2015-02-27 10:50:43.243'),
('0001','2015-02-27 10:50:43.243','2015-03-02 08:52:35.000'),
('0001','2015-03-02 08:52:35.000','2015-03-02 12:43:30.790 '),
('0001','2015-03-02 12:43:30.790','2015-03-02 17:29:02.147'),

('0001','2015-03-03 12:43:30.790','2015-03-06 17:29:02.147'),
('0001','2015-03-15 12:43:30.790','2015-03-16 17:29:02.147'),
('0001','2015-03-16 17:29:02.147','2015-03-17 17:29:02.147')


declare @startDate date, @endDate date
set @startDate = (select min(cast([Start datetime] as date)) from #tempTable)
set @endDate = (select max(cast([End datetime] as date)) from #tempTable)

;with cteDates as(
   select @startDate as myDate
   union all
   select dateadd(day,1,myDate) as myDate
   from cteDates
   where dateadd(day,1,myDate) <= @endDate)

select
    myDate,
    MRN,
    min([Start datetime]) as [Start datetime],
    max([End datetime]) as [End datetime]
from
    cteDates
right join
    #tempTable on myDate >= cast([Start datetime] as date) and myDate <= cast([End datetime] as date)
group by
    myDate, MRN
option (maxrecursion 0)
结果


绝对不要为此使用光标。我在下面给了您一个递归CTE,它可以做您想做的事情,而无需在数据库中创建任何新表。如果您经常这样做,您可能只想创建一个日历表,列出若干年中的所有日期。如果你按这个名字搜索,你会发现许多类似的问题和有用的参考资料。更新为@g为你处理日期时间问题。senorsenor@g.senorsenor你能告诉我你用什么数据测试这个吗?也别忘了投票选出有用的答案,并接受正确的答案。非常感谢你的帮助。我在原问题中列出了我的问题!又多了thanks@g.senorsenor不知道你为什么会这样。你能检查一下你的数据吗?我在这里添加了一些测试数据来显示you@scsimonThanks再次寻求帮助。我更新了问题above@g.senorsenor更新了答案并添加了更多的数据行以供测试。这会让你到达你需要的地方。。。您可以根据需要进行编辑