2017-02-01 5 views
2

私はこのようなデータを持つ2つのテーブル(実際にそこ4がありますが、今のところ、それは2だと言うことができます)があります。有効期間 - SQLのVIEW

Table PersonA 
ClientID ID From  Till 
1   10 1.1.2017 30.4.2017 
1   12 1.8.2017 2.1.2018 

Table PersonB  
ClientID ID From  Till 
1   6 1.3.2017 30.6.2017 

をそして、私はこのような何かを示すだろうビューを生成する必要があります:

ClientID  From  Till  PersonA  PersonB 
1    1.1.2017 28.2.2017 10   NULL 
1    1.3.2017 30.4.2017 10   6 
1    1.5.2017 30.6.2017 NULL   6 
1    1.8.2017 02.1.2018 12   NULL 

したがって、基本的に私は、各クライアントが与えられた期間中に持っていた "人"を示すビューを作成する必要があります。
重複がある場合、クライアントはPersonAとPersonBの両方を持ちます(PersonCとPersonDにも同じことが適用されます)。
最後のビューでは、1つのクライアントに重複する日付を設定することはできません。

私はこれにどのようにアプローチするのか分かりません。

+0

テーブルと4つのPersonテーブルがあります。これを行う目的は?追加値の列を追加することは、一般に、セットベースのクエリの原則に反するため、SQLの習慣としては貧弱です。あなたが割り当てられた月と人のリストが必要な場合は、プレゼンテーション層でフォーマットされた通常のデータセットを使用する方がよいでしょう。 – iamdave

+0

@iamdave - これはちょうど私が与えられた仕事です。私はそれも好きではありませんし、私は別のアプローチを見つけることを試みるでしょうが、今私はこれに固執しています – quin61

+0

再び、どのような目的のために?データはどこで使用されるのでしょうか?分析のために優れている場合は、標準データセットをピボットすることができます。 SSRSのようなレポートレイヤーを使用している場合は、そこでピボットすることができます。私はあなたがこのフォーマットのデータを他の用途のためのクエリから直接求められていると信じることを拒否しますか? – iamdave

答えて

3

this algorithmの適応では、我々はすでに重複を扱うことができます。質問に与えられたわずか2つのPersonテーブルと

declare @PersonA table(ClientID int, ID int, [From] date, Till date); 
insert into @PersonA values (1,10,'20170101','20170430'),(1,12,'20170801','20180112'); 

declare @PersonB table(ClientID int, ID int, [From] date, Till date); 
insert into @PersonB values (1,6,'20170301','20170630'); 

declare @PersonC table(ClientID int, ID int, [From] date, Till date); 
insert into @PersonC values (1,12,'20170401','20170625'); 

declare @PersonD table(ClientID int, ID int, [From] date, Till date); 
insert into @PersonD values (1,14,'20170501','20170525'),(1,14,'20170510','20171122'); 

with X(ClientID,EdgeDate) 
    as (select ClientID 
       ,case 
        when toggle = 1 
         then Till 
        else [From] 
       end as EdgeDate 
     from 
       (
       select ClientID,[From],Till from @PersonA 
       union all 
       select ClientID,[From],Till from @PersonB 
       union all 
       select ClientID,[From],Till from @PersonC 
       union all 
       select ClientID,[From],Till from @PersonD 
      ) as concated 
      cross join 
       (
       select-1 as toggle 
       union all 
       select 1 as toggle 
      ) as toggler 
),merged 
    as (select distinct 
       S.ClientID 
       ,S.EdgeDate as [From] 
       ,min(E.EdgeDate) as Till 
     from 
       X as S 
      inner join X as E 
       on S.ClientID = E.ClientID 
        and S.EdgeDate < E.EdgeDate 
     group by S.ClientID 
       ,S.EdgeDate 
),prds 
    as (select distinct 
       merged.ClientID 
       ,merged.[From] 
       ,merged.Till 
       ,A.ID as PersonA 
       ,B.ID as PersonB 
       ,C.ID as PersonC 
       ,D.ID as PersonD 
     from 
       merged 
      left join @PersonA as A 
       on merged.ClientID = A.ClientID 
        and A.[From] <= merged.[From] 
        and merged.Till <= A.Till 
      left join @PersonB as B 
       on merged.ClientID = B.ClientID 
        and B.[From] <= merged.[From] 
        and merged.Till <= B.Till 
      left join @PersonC as C 
       on merged.ClientID = C.ClientID 
        and C.[From] <= merged.[From] 
        and merged.Till <= C.Till 
      left join @PersonD as D 
       on merged.ClientID = D.ClientID 
        and D.[From] <= merged.[From] 
        and merged.Till <= D.Till 
     where not(A.ID is null 
        and B.ID is null 
        and C.ID is null 
        and D.ID is null 
       ) 
) 
select ClientID 
    ,[From] 
    ,case 
     when Till = lead([From] 
       ) over(order by Till) 
      then dateadd(d,-1,Till) 
     else Till 
    end as Till 
    ,PersonA 
    ,PersonB 
    ,PersonC 
    ,PersonD 
from 
    prds 
order by ClientID 
     ,[From] 
     ,Till; 

出力:スクリプトの

+----------+------------+------------+---------+---------+ 
| ClientID | From | Till | PersonA | PersonB | 
+----------+------------+------------+---------+---------+ 
|  1 | 2017-01-01 | 2017-02-28 | 10  | NULL | 
|  1 | 2017-03-01 | 2017-04-29 | 10  | 6  | 
|  1 | 2017-04-30 | 2017-06-30 | NULL | 6  | 
|  1 | 2017-08-01 | 2018-01-12 | 12  | NULL | 
+----------+------------+------------+---------+---------+ 

出力、それは上記のようです

+----------+------------+------------+---------+---------+---------+---------+ 
| ClientID | From | Till | PersonA | PersonB | PersonC | PersonD | 
+----------+------------+------------+---------+---------+---------+---------+ 
|  1 | 2017-01-01 | 2017-02-28 | 10  | NULL | NULL | NULL | 
|  1 | 2017-03-01 | 2017-03-31 | 10  | 6  | NULL | NULL | 
|  1 | 2017-04-01 | 2017-04-29 | 10  | 6  | 12  | NULL | 
|  1 | 2017-04-30 | 2017-04-30 | NULL | 6  | 12  | NULL | 
|  1 | 2017-05-01 | 2017-05-09 | NULL | 6  | 12  | 14  | 
|  1 | 2017-05-10 | 2017-05-24 | NULL | 6  | 12  | 14  | 
|  1 | 2017-05-25 | 2017-06-24 | NULL | 6  | 12  | 14  | 
|  1 | 2017-06-25 | 2017-06-29 | NULL | 6  | NULL | 14  | 
|  1 | 2017-06-30 | 2017-07-31 | NULL | NULL | NULL | 14  | 
|  1 | 2017-08-01 | 2017-11-21 | 12  | NULL | NULL | 14  | 
|  1 | 2017-11-22 | 2018-01-12 | 12  | NULL | NULL | NULL | 
+----------+------------+------------+---------+---------+---------+---------+ 
+0

私はこのクエリから得る出力は、質問に一致しません。人の新しい組み合わせごとに行/期間を表示していません。ありがとう。 – iamdave

+0

ありがとうございました。 OPのサンプルデータの日付は一貫性がありませんが、私は考えを得ます...修正しようとしましょう。 – dlatikay

+2

彼らは私に意味をなさない、重複することを意味する。出力は、組み合わせが開始された日付と終了された日付、およびどのPersonが含まれているかによって、Personの異なる組み合わせの開始日と終了日の行にする必要があります。 – iamdave

関連する問題