2016-11-25 9 views
0

私はYYYYMM形式の時系列を持つこのデータセットを持っています。私は基本的に真偽フラグとして2つの列を持っています。 、06、あなたは05、期間201304のために1に設定されているデフォルトの列を見ることができる私は、このデータセットT-SQL:Timeseriesの塗りつぶし範囲

 Default Cure 
201301 0  NULL 
201302 0  NULL 
201303 0  NULL 
201304 1  NULL 
201305 1  NULL 
201306 1  NULL 
201307 1  NULL 
201308 NULL  0 
201309 NULL  0 
201310 NULL  1 
201311 0  NULL 
201312 0  NULL 
201401 0  NULL 
201402 0  NULL 
201403 1  NULL 
201404 1  NULL 
201405 0  NULL 
201406 0  NULL 
201407 NULL  1 
201408 NULL  0 
201409 NULL  0 
201410 NULL  0 
201411 NULL  0 
201412 NULL  0 

:私は、現在の範囲を取得し、これらの真/偽のフラグに基づいて2つの余分な列を追加したいと思います07とキュア列が期間201310.

に1に設定されているこれは、基本的にはデフォルトの時系列を意味し最終的に私は、次のセットを生成したい期間201304から期間201310.まで有効です。

 Default Cure DefaultPeriod CurePeriod 
201301 0  NULL NULL   NULL 
201302 0  NULL NULL   NULL 
201303 0  NULL NULL   NULL 
201304 1  NULL 201304   201310 
201305 1  NULL 201304   201310 
201306 1  NULL 201304   201310 
201307 1  NULL 201304   201310 
201308 NULL  0  201304   201310 
201309 NULL  0  201304   201310 
201310 NULL  1  201304   201310 
201311 0  NULL NULL   NULL 
201312 0  NULL NULL   NULL 
201401 0  NULL NULL   NULL 
201402 0  NULL NULL   NULL 
201403 1  NULL 201403   201407 
201404 1  NULL 201403   201407 
201405 0  NULL 201403   201407 
201406 0  NULL 201403   201407 
201407 NULL  1  201403   201407 
201408 NULL  0  NULL   NULL 
201409 NULL  0  NULL   NULL 
201410 NULL  0  NULL   NULL 
201411 NULL  0  NULL   NULL 
201412 NULL  0  NULL   NULL 

複数の範囲が発生する可能性がありますが、オーバーラップこれを達成するにはどうすればいいですか?私はすべての種類の最小/最大期間を同じテーブルで結合しようとしましたが、実際の解決策を見つけることができません。

+0

あなたは、「基本的に真偽フラグとして2列ありますが...」と言っていますが、「NULL」値もあります。 'NULL == 0 == FALSE'を使用していますか?もしそうなら、 'NULL'フィールドに' 0'を設定するだけではどうですか? – Tony

+0

'201308'では、' Cure'の '0'値は範囲を維持しますが、' Default'の '0'値は' 201311'で範囲を進ませません。何故なの? '201405'の' Default' *の '0'値は、やはり範囲を守っています... – AakashM

+0

基本的には、あなたの説明や例から明らかではありません。 false b)範囲を構成するものの周りにあるルル – AakashM

答えて

1

これが本当の思想家だった:)

基本的に私は、「キュア」の日付(C1)上のデータを分割する各グループ(C2)の番号付け、その後、分を探していると、各グループ内でmaxesています(C3 C4)、その後、minの前に来る行をフィルタリングするロジックを適用します。

declare @t table 
(
    [Month] varchar(6), 
    [Default] bit, 
    [Cure] bit 
); 

insert into @t values('201301', 0,  NULL); 
insert into @t values('201302', 0,  NULL); 
insert into @t values('201303', 0,  NULL); 
insert into @t values('201304', 1,  NULL); 
insert into @t values('201305', 1,  NULL); 
insert into @t values('201306', 1,  NULL); 
insert into @t values('201307', 1,  NULL); 
insert into @t values('201308', NULL,  0); 
insert into @t values('201309', NULL,  0); 
insert into @t values('201310', NULL,  1); 
insert into @t values('201311', 0,  NULL); 
insert into @t values('201312', 0,  NULL); 
insert into @t values('201401', 0,  NULL); 
insert into @t values('201402', 0,  NULL); 
insert into @t values('201403', 1,  NULL); 
insert into @t values('201404', 1,  NULL); 
insert into @t values('201405', 0,  NULL); 
insert into @t values('201406', 0,  NULL); 
insert into @t values('201407', NULL,  1); 
insert into @t values('201408', NULL,  0); 
insert into @t values('201409', NULL,  0); 
insert into @t values('201410', NULL,  0); 
insert into @t values('201411', NULL,  0); 
insert into @t values('201412', NULL,  0); 


with c1 as 
(
    select min([Month]) [Month], 1 x from @t 
    union all 
    select [Month],1 from @t 
    where Cure = 1 
), 
c2 as 
(
    select t.[Month],[Default],[Cure], 
     sum(x) over (order by t.[Month] rows between unbounded preceding and 1 preceding) grp 
    from @t t 
    left outer join c1 on c1.[Month] = t.[Month] 
), 
c3 as 
(
    select grp, min([Month]) [Month] 
    from c2 
    where [Default] = 1 
    group by grp 
), 
c4 as 
(
    select grp, max([Month]) [Month] 
    from c2 
    where [Cure] = 1 
    group by grp 
) 
select c2.[Month], c2.[Default], c2.[Cure], 
    case when c2.[Month] >= c3.[Month] then c3.[Month] else null end as DefaultPeriod, 
    case when c2.[Month] >= c3.[Month] then c4.[Month] else null end as CurePeriod 
from c2 
left outer join c3 on c2.grp = c3.grp 
left outer join c4 on c2.grp = c4.grp 
関連する問題