2016-09-22 6 views
1

1つのテーブルの時間を1つのテーブルの期間(開始時刻と終了時刻)と照合して2つのテーブルに結合したいのですが、操作によって1つのテーブルの正確な情報が保持されるようにする必要があります。具体的には、私はこれらのテーブルを持っています。1つのテーブルの正確な情報を保持しながらテーブルを結合するにはどうすればよいですか?

表T1:

cid time1 
A  2016-01-05 11:00:00 
A  2016-01-15 11:00:00 
A  2016-01-25 11:00:00 
B  2016-01-09 11:00:00 

表T2:

cid period_start   period_end 
A  2016-01-01 00:00:00 2016-01-10 00:00:00 
A  2016-01-10 00:00:00 2016-01-16 00:00:00 
A  2016-01-12 00:00:00 2016-01-20 00:00:00 

そして私はのような出力をしたい:いくつかの追加情報/条件

cid time1     period_start   period_end 
A  2016-01-05 11:00:00 2016-01-01 00:00:00 2016-01-10 00:00:00 
A  2016-01-15 11:00:00 2016-01-10 00:00:00 2016-01-16 00:00:00 
A  2016-01-25 11:00:00 NULL     NULL 
B  2016-01-09 11:00:00 NULL     NULL 

  • t1の情報を出力に正確に保存したいとします(たとえば、t1の行がt2の複数の行に結合されず、t1の行が出力に欠けていないなど)。言い換えれば、t2の情報をt1に列として追加したいだけです。
  • t1にtime1を含む期間がt2にない場合は、period_startとperiod_endをNULLにします。
  • t2には一致するcidも全くない可能性があります。
  • t2に複数のマッチがある場合は、最初のものだけを必要とします。

    SELECT t1.*, t2.period_start, t2.period_end 
    FROM t1 
        LEFT JOIN t2 ON t1.cid = t2.cid 
    WHERE t2.period_start >= t1.time1 
    AND t2.period_end <= t1.time1 
    

    をしかし、一致するものがないところでは、適切なシナリオを処理しない:

は、今私が持っています。これどうやってするの?

私はこれをRedshiftでやっています。

答えて

1

あなたはt2からのみ、最初に一致した行をしたいので、あなたはLIMIT句でLATERALサブクエリを使用することができます。T1 1月15日は中二列に参加しますので、それは私のために動作しません

SELECT t1.cid, t1.time1, t2.period_start, t2.period_end 
FROM t1 LEFT JOIN LATERAL 
    (SELECT * 
     FROM t2 
     WHERE cid=t1.cid AND t1.time1 BETWEEN period_start AND period_end 
     ORDER BY t2.period_start 
     LIMIT 1 
    ) t2 ON true 
+0

素晴らしい、ありがとう! –

1
参加

FROM t1 LEFT JOIN t2 ep ON t1.cid = t2.cid 
and t2.period_start >= t1.time1 
AND t2.period_end <= t1.time1 

にwhere句からT2にフィルタを移動

どこ句左結合テーブルをフィルタリングする場合、結合のタイプは、内部に変更されます。

+0

t2。私は最初のものだけが必要です。 –

1

次のクエリを使用することができます。

SELECT cid, time1, period_start, period_end 
FROM (
    SELECT t1.cid, t1.time1, t2.period_start, t2.period_end, 
      ROW_NUMBER() OVER (PARTITION BY t1.cid, t1.time1 
          ORDER BY t2.period_start) AS rn 
    FROM t1 
    LEFT JOIN t2 ON t1.cid = t2.cid AND 
        t1.time1 BETWEEN t2.period_start AND t2.period_end) AS t 
WHERE t.rn = 1    

ROW_NUMBERは、複数の一致がある場合にはt1テーブルから一つのレコードを選択するために使用されています。

+0

素晴らしいです、ありがとう! –

関連する問題