2016-04-04 7 views
0

テーブル内のユーザごとに異なる時間を費やしています。期間は重複しており、私はそれを修正したいと思います。私は持っている:PostgreSQL、重複期間の発見と修正

user|unit|start_time|end_time 
    1| 1|2015-01-01|2015-01-31 
    1| 2|2015-01-07|2015-01-14 
    2| 1|2015-01-09|2015-01-13 
    2| 2|2015-01-10|2015-01-15 

ie。ユーザ1は2015-01-01でユニット1で開始し、2015-01-07でユニット2に転送し、2015-01-14でユニット1に戻り、2015-01-31でユニット1を戻しました。ユーザーは一度に2か所にいることはできませんので、テーブルは次のようになります。

user|unit|start_time|end_time 
    1| 1|2015-01-01|2015-01-07 --fixed end_time 
    1| 2|2015-01-07|2015-01-14 
    1| 1|2015-01-14|2015-01-31 --newly created line 
    2| 1|2015-01-09|2015-01-10 --fixed end_time 
    2| 2|2015-01-10|2015-01-15 

いくつかのエントリを持つテストテーブルを作成するためのSQLがあります。

CREATE TABLE users_n_units 
(
users character varying (100), 
units character varying (100), 
start_time date, 
end_time date 
); 

INSERT INTO users_n_units (users,units,start_time,end_time) 
VALUES ('1','1','2015-01-01','2015-01-31'), 
     ('1','2','2015-01-07','2015-01-14'), 
     ('2','1','2015-01-09','2015-01-13'), 
     ('2','2','2015-01-10','2015-01-15'); 
+0

3つのユニットが重なっている場合はどうなりますか? –

+0

まあ私のデータは2つのユニットしか持っていないので、3つは重なり合うことはできませんが、一般的に後発イベントは前回開始イベントを終了し、後発イベントが終了しても早期開始が続く場合でも、元の終了時刻まで。オーバーラップするイベントが2つ以上ある場合、後者は常に前の開始を終了し、開始時間の順番を守る必要があります。 –

答えて

0

あなたは本当に完全にこれに答えるために十分な情報を与えていない、と他の人が指摘したように、あなたのデータが更新を実行する前に、慎重にどのように見えるかを分析する必要がありますので、あなたは特別な場合で終わることがあります。

しかし、あなたのテスト環境では、このようなものを試すことができます。そのトリックは、ビジネスロジックと適切に一致するデータに制限する句を使用してテーブルを結合し、それを更新することです。

このステートメントは、ごくわずかなサンプルセットで動作し、終了時間を次の期間の開始時間に機械的に設定します。私はこれに似た何かを似たような問題に使用していましたので、そのメカニズムがあなたのために働くはずです。

注意:この小さなセット以外はテストしません。実稼働データで実行しないでください!

UPDATE a SET a.end_time = b.start_time 
FROM users_n_units a 
INNER JOIN users_n_units b ON a.users = b.users AND a.units < b.units 
+0

これはPostgreSQLのままでは実行されませんでしたが、それを修正した後、結果テーブルには4行しかありませんでした。 –

関連する問題