これを試してください:http://www.sqlfiddle.com/#!3/c3365/ 20
with s as( select *, row_number() over(membercode による分割、開始日による順序) rn from tbl),gaps as(select a.membercode, a.startdate, a.enddate, b.startdate as nextstartdate ,datediff(d, a.enddate, b.startdate) as gapfrom s ajoin s b on b.membercode =a.membercode and b.rn =a.rn + 1)select membercode from gapsgroup by membercodehaving sum(gap <の場合) =1 なら 1 エンド) =count(*);
プレ>ここでクエリの進行状況を確認してください:http://www.sqlfiddle.com/#!3/ c3365/20
仕組み、現在の終了日と次の開始日を比較し、日付のギャップを確認します:
with s as( select *, row_number() over(partition by membercode order by startdate) rn from tbl)select a.membercode, a.startdate, a.enddate, b.startdate as nextstartdate ,datediff( d, a.enddate, b.startdate) as gapfrom s ajoin s b on b.membercode =a.membercode and b.rn =a.rn + 1;
プレ>出力:
<プレ>|メンバーコード |開始日 |終了日 | NEXTSTARTDATE |ギャップ |------------------------------------------------ --------------| 1 | 2010-01-15 | 2010-01-20 | 2010-01-19 | -1 || 1 | 2010-01-19 | 2010-01-22 | 2010-01-20 | -2 || 1 | 2010-01-20 | 2010-01-25 | 2010-01-26 | 1 || 2 | 2010-01-20 | 2010-01-25 | 2010-01-30 | 5 || 2 | 2010-01-30 | 2010-02-05 | 2010-02-04 | -1 |
プレ>次に、メンバーが同じ数の請求を行っており、請求の合計にギャップがないかどうかを確認します。
with s as( select *, row_number() over(membercode による分割、開始日による順序) rn from tbl),gaps as(select a.membercode, a.startdate, a.enddate, b.startdate as nextstartdate ,datediff(d, a.enddate, b.startdate) as gapfrom s ajoin s b on b.membercode =a.membercode and b.rn =a.rn + 1)membercode を選択し、count(*) を count として、sum( case when gap <=1 then 1 end) as gapless_countfrom gapsgroup by membercode;
プレ>出力:
<プレ>|メンバーコード |カウント | GAPLESS_COUNT |----------------------------------------------------| 1 | 3 | 3 || 2 | 2 | 1 |コード> プレ>
最後に、主張にギャップのないメンバーをフィルタリングします:
with s as( select *, row_number() over(membercode による分割、開始日による順序) rn from tbl),gaps as(select a.membercode, a.startdate, a.enddate, b.startdate as nextstartdate ,datediff(d, a.enddate, b.startdate) as gapfrom s ajoin s b on b.membercode =a.membercode and b.rn =a.rn + 1)select membercode from gapsgroup by membercodehaving sum(gap <の場合) =1 なら 1 エンド) =count(*);
プレ>出力:
<プレ>|メンバーコード |-------------| 1 |コード> プレ>
COUNT(*)> 1
を実行する必要がないことに注意してください 2 つ以上のクレームを持つメンバーを検出します。LEFT JOIN
を使用する代わりに 、JOIN
を使用します 、これにより、まだ 2 番目の要求を持っていないメンバーは自動的に破棄されます。LEFT JOIN
を使用することを選択した場合のバージョン (より長い) は次のとおりです。 代わりに (上記と同じ出力):with s as(select *, row_number() over(partition by membercode order by startdate) rnfrom tbl),gaps as(select a.membercode, a.startdate, a.enddate, b.startdate as nextstartdate ,datediff(d, a.enddate, b.startdate) as gapfrom s aleft join s b on b.membercode =a.membercode and b.rn =a.rn + 1)select membercode from gapsgroup by membercodehaving sum(case when gap <=1 その後 1 エンド) =カウント (ギャップ) およびカウント (*)> 1; -- 2 つ以上のクレームのみを持つメンバー
プレ>フィルタリング前に上記のクエリのデータを表示する方法は次のとおりです:
with s as( select *, row_number() over(membercode による分割、開始日による順序) rn from tbl),gaps as(select a.membercode, a.startdate, a.enddate, b.startdate as nextstartdate ,datediff(d, a.enddate, b.startdate) as gapfrom s aleft join s b on b.membercode =a.membercode and b.rn =a.rn + 1)select * from gaps;
プレ>出力:
<プレ>|メンバーコード |開始日 |終了日 | NEXTSTARTDATE |ギャップ |------------------------------------------------ ------------------| 1 | 2010-01-15 | 2010-01-20 | 2010-01-19 | -1 || 1 | 2010-01-19 | 2010-01-22 | 2010-01-20 | -2 || 1 | 2010-01-20 | 2010-01-25 | 2010-01-26 | 1 || 1 | 2010-01-26 | 2010-01-30 | (ヌル) | (ヌル) || 2 | 2010-01-20 | 2010-01-25 | 2010-01-30 | 5 || 2 | 2010-01-30 | 2010-02-05 | 2010-02-04 | -1 || 2 | 2010-02-04 | 2010-02-15 | (ヌル) | (ヌル) || 3 | 2010-02-15 | 2010-03-02 | (ヌル) | (ヌル) |
プレ>編集 要件の明確化について:
あなたの説明では、まだ 2 番目のクレームも持っていないメンバーを含めたいと考えていましたが、代わりにこれを行います:>http://sqlfiddle.com/#!3/c3365/22
with s as(select *, row_number() over(partition by membercode order by startdate) rnfrom tbl),gaps as(select a.membercode, a.startdate, a.enddate, b.startdate as nextstartdate ,datediff(d, a.enddate, b.startdate) as gapfrom s aleft join s b on b.membercode =a.membercode and b.rn =a.rn + 1)select membercode from gapsgroup by membercodehaving sum(case when gap <=1 then 1 end) =count(gap)-- まだ 2 番目のクレームを持っていないメンバーも有効または count(nextstartdate) =0; コード> プレ>
出力:
<プレ>|メンバーコード |-------------| 1 || 3 |コード> プレ>
手法は、メンバーの
nextstartdate
をカウントすることです 、次の開始日がない場合 (つまり、count(nextstartdate) =0
) その場合、それらは単一のクレームのみであり、有効でもあります。このOR
を添付するだけです 状態:or count(nextstartdate) =0; コード> プレ>
実際には、以下の条件でも十分ですが、クエリをより自己文書化したかったので、メンバーの nextstartdate に頼ることをお勧めします。 2 番目の要求をまだ持っていないメンバーをカウントするための別の条件は次のとおりです:
or count(*) =1;
プレ>ところで、次の比較も変更する必要があります:
sum(case when gap <=1 then 1 end) =count(*)
プレ>これに (
LEFT JOIN
を使用しているため) 今):sum(case when gap <=1 then 1 end) =count(gap)
プレ>