2016-08-17 8 views
2

彼らは「日時を起動」と「日時を開始します」の中で、私は、私は数多くの列を持つテーブルを持っているSQL Server 2008の複数の 'start datetime'と 'end datetime'です。開始日時と終了日時

を使用している間の各日付の新しい行を生成します。したがって、各行には1つの 'Start datetime'と1つの 'End datetime'があります。 行ごとに 'Start datetime'と 'End datetime'の間に毎日新しい行を生成する必要があります。私はこの表を使用して、病院で占められているICUベッドの1日量を生成します。私のテーブルで

サンプルデータ:

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で初心者だと簡単に混乱しています。理想的には、既存のクエリを変更せずに既存のクエリを本体に貼り付けることができます。私はドロップテーブルを使用しないほうがいいです。これは最終的に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 

所望の出力:以下

@scsimon

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 

こんにちはは、実際のデータです。もう一度助けてくれてありがとう。私は実際に休暇中ですので、私のインターネットは不安定ですので、遅い返事を許してください。私が気づいたデータを見直す際には、患者が同じ日付に2回移され、「開始日時」と「終了日時」が異なる時刻の同じ日付になるようにすることはできません。私はこれが私の問題の原因だと信じています。 'Start datetime'と 'End datetime'が同じ日付である必要がある場合は、同じ日付がNULLに等しいすべての行の 'Mydate'。私の定型化を許して、それはフォーマットするのがとても長いです。助けてくれてありがとう。

マイデータ:あなたと仮定すると

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

は間違いなく、このためのカーソルを使用しないでください。私はあなたのDB内に新しいテーブルを作成せずに望むことをやり遂げることができる再帰的なCTEを教えました – scsimon

+1

あなたがこれをたくさんしていることが分かった場合は、いくつかの番号のすべての日付をリストする "カレンダーテーブル"年。その名前で検索すると、多くの同様の質問と参考になる参考文献が見つかります。 – shawnt00

+0

@ g.senorsenorのdatetimeの問題を処理するように更新されました – 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は、開始日> = DateTable.Dateと終了日< = DateTable.Date ON」とその日付テーブルへのJOINありません" 調子。

このテーブルがない場合は、物理テーブル、一時テーブル、テーブル変数、テーブル関数など、簡単に再作成できます。

代替ソリューション - 再帰的なCTEですが、物理的に事前入力された日付表がある場合は、上記のソリューションよりも優れたパフォーマンスを発揮しません。

関連する問題