2016-12-20 5 views
0

は、私は次のような構造を持つテーブルで日付のクラスタを見つけたい:私はこのクラスタ内の最初の日から7(またはその他の間隔)日以内の日付のクラスタを見つけたいSQLパーpostgreSQLで日付クラスタを見つける方法は?

patientID | dt 
---------- | ---------- 
1   | 2016-05-03 
1   | 2016-05-05 
1   | 2016-05-07 
2   | 2016-07-12 
2   | 2016-07-15 
2   | 2016-07-18 
1   | 2016-07-13 
1   | 2016-07-14 

。通常、2つの連続したクラスタ間のギャップは7以上であるため、この問題は無視できます。私の最初のアプローチは機能せず、理由はないが、(集計でグループすることはできません)が、私は私の問題を解決するためにどのようにさっぱりだが、それは明らかだ

patientID | min(dt) | max(dt) | count(dt) 
---------- | ---------- | ---------- | --------- 
1   | 2016-05-03 | 2016-05-07 | 3 
2   | 2016-07-12 | 2016-07-18 | 3 
1   | 2016-07-13 | 2016-07-14 | 2 

select t0.patientID, min(t0.dt), max(t0.dt), count(*) 
from tbl t0 
join tbl t1 on t0.patientID=t1.patientID and t1.dt - t0.dt between 1 and 7 
group by t0.patientID, min(t0.dt); 
+0

'generate_series(start :: date、end :: date、 '7 days' :: interval)'に参加したくないですか? –

答えて

0
のような結果がでなければなりません

これは2つの異なる問題です。 2番目の問題は、7日以上に分かれたクラスタを見つけることは、SQLで解決するのが簡単な問題です。あなたは、日付の差を計算するlag()から旗を作成し、累積和および凝集を使用するようにlag()を使用してこれを行うことができます。

select patientid, min(dt), max(dt), count(*) 
from (select t.*, 
      sum((case when dt > prev_dt + interval '7 day' then 1 else 0 end) 
       ) over (partition by patientid order by dt) as grp 
     from (select t.*, 
        lag(dt) over (partition by patientid order by dt) as prev_dt 
      from t 
      ) t 
    ) t 
group by patientid, grp; 

あなたが記述第一の問題は、再帰CTEを必要とし、処理がはるかになりますもっとゆっくり。

+0

これは私の問題を解決しました。 CTEの必要はありません。どうもありがとう! – kwrl

関連する問題