タイムスタンプの範囲とユーザーIDを含むPostgreSQL(9.4)の表があり、重複する範囲(同じユーザーID)を1つのレコードに集約する必要があります。PostgreSQLの時間範囲が重複しています
これを達成するために複雑なCTEを試しましたが、私たちの(40,000+行)実テーブルにはいくつかの問題があり、問題を複雑にしています。私はおそらく再帰的なCTEが必要であるという結論に達しましたが、私はそれを書いている運がありませんでした。
テストテーブルを作成し、データを入力するコードです。これは私たちのテーブルのレイアウトではありませんが、例のためには十分に近いです。私は、個々のレコードは、以前、使用してウィンドウと重なっているかどうかを判断するためにこれを使用することができ
select * from test order by fk_user_id, sessionrange
:私は、彼らが開始された時刻によってソートされたセッションを取得するには、この操作を行うことができることを発見した
CREATE TABLE public.test
(
id serial,
sessionrange tstzrange,
fk_user_id integer
);
insert into test (sessionrange, fk_user_id)
values
('[2016-01-14 11:57:01-05,2016-01-14 12:06:59-05]', 1)
,('[2016-01-14 12:06:53-05,2016-01-14 12:17:28-05]', 1)
,('[2016-01-14 12:17:24-05,2016-01-14 12:21:56-05]', 1)
,('[2016-01-14 18:18:00-05,2016-01-14 18:42:09-05]', 2)
,('[2016-01-14 18:18:08-05,2016-01-14 18:18:15-05]', 1)
,('[2016-01-14 18:38:12-05,2016-01-14 18:48:20-05]', 1)
,('[2016-01-14 18:18:16-05,2016-01-14 18:18:26-05]', 1)
,('[2016-01-14 18:18:24-05,2016-01-14 18:18:31-05]', 1)
,('[2016-01-14 18:18:12-05,2016-01-14 18:18:20-05]', 3)
,('[2016-01-14 19:32:12-05,2016-01-14 23:18:20-05]', 3)
,('[2016-01-14 18:18:16-05,2016-01-14 18:18:26-05]', 4)
,('[2016-01-14 18:18:24-05,2016-01-14 18:18:31-05]', 2);
機能:
SELECT *, sessionrange && lag(sessionrange) OVER (PARTITION BY fk_user_id ORDER BY sessionrange)
FROM test
ORDER BY fk_user_id, sessionrange
しかし、これはただ一つ前のレコードは、現在の1(レコードid = 6
を参照)と重なるかどうかを検出します。私は、パーティションの始めまでずっと検出する必要があります。
その後、最も早いセッションの開始と終了する最後のセッションの終了を見つけるために、一緒に重なるレコードをグループ化する必要があります。
私は見落としていることをこれを行う方法があると確信しています。これらの重複するレコードをどのように崩壊させることができますか?
それが収まるように全く適合させる必要はありませんでしたので、私は、最初のソリューションと一緒に行くことになったが私の実際のスキーマ。これは本当に簡単に作業して正しいと思われます。私は確かにいくつかの追加のテストをする必要がありますが、私はあなたの答えを受け入れるために今日後でここに戻ってくると思います。ありがとうございました! –
いくつかのテストを行いましたが、これは私が望むようにすべてを組み合わせたように見えます。ありがとう! –
あなたの質問は私の挑戦であることが判明しました。立てられない私は機能なしでそれをすることはできません;) – klin