2016-08-17 170 views
2

我使用SQL Server 2008的多個「開始日期時間」和「結束日期時間」。生成的開始日期時間和結束日期時間

我有一個表與衆多欄目,其中「開始日期時間」和「開始日期時間」之間的每個日期一個新行。因此每行都有一個「開始日期時間」和一個「結束日期時間」。 我需要爲每一行之間'Start datetime'和'End datetime'每行生成一個新行。我將使用這張表來生成在醫院中佔用的每日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 

我已經試過光標和一些CTE,但我在SQL新手和感到困惑容易。理想情況下,解決方案將允許我將現有查詢粘貼到其正文中,而無需修改現有查詢。我不想使用drop table,因爲它最終會被輸入到畫面並每天更新。

從我的經驗表不能處理drop table。謝謝你的幫助。

謝謝@scsimon你的建議幫了大忙!唯一的問題是你的cte不會在'desired output'中產生第一行,見下文。

輸出使用點擊率:

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 

嗨@scsimon

下面是實際數據。再一次感謝你的幫助。我實際上正在度假,所以我的網絡很差,所以請原諒遲到的回覆。在審查數據時,我意識到我忽略了包括可能在同一天轉讓患者兩次,因此'開始日期時間'和'結束日期時間'是不同時間的同一日期。我相信這是我的問題的原因。對於'開始日期時間'和'結束日期時間'是相同日期的所有行,'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 
+0

絕對不使用這個遊標。我給了你一個遞歸的CTE下面,將做你想要的,而不是在你的數據庫中創建任何新表格 – scsimon

+1

如果你發現自己做了很多,你可能只是想創建一個「日曆表」列出所有日期跨越一些年份。如果你用這個名字搜索,你會發現很多類似的問題和有用的參考資料。 – shawnt00

+0

已更新,以便爲您處理日期時間問題@ g.senorsenor – scsimon

回答

0

首先創建日期的CTE,然後加入到您的數據爲每個日期製作1行....

--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) 

成績

results

+0

@ g.senorsenor您能告訴我您測試過的數據是什麼嗎?也不要忘記投票有用的答案,並接受正確的答案 – scsimon

+0

非常感謝您的幫助。我在上面的問題中列出了我的問題!再次非常感謝 –

+0

@ g.senorsenor不知道你爲什麼這樣做。你能檢查你的數據嗎?我在這裏添加了一些測試數據以再次向您展示 – scsimon

0

假設你有日期表在你的數據庫

只是不要INNER JOIN與「此日期表ON起始日期> = DateTable.Date日期和結束日期< = DateTable.Date 「條件。

如果您沒有該表格,可以輕鬆重新創建 - 物理表格,臨時表格,表格變量或表格功能。

替代解決方案 - 遞歸CTE,但如果您有物理預填充日期表,它不會比上述解決方案執行得更好。

相關問題