1

左側のテーブルの日付値が右側のテーブルのタイムスロットに収まる2つのテーブル間の結合を作成しようとしています。したがって、たとえば、私が持っている場合:

TABLE A                      TABLE B
ID    TIMESTMP               ID    TIMESMTP             VALUE
1     8/31/2012 2:00 PM      1     8/30/2012 4:00 AM    A
2     8/29/2012 3:00 PM      1     8/31/2012 1:00 PM    B
3     7/04/2012 5:00 AM      1     8/31/2012 3:00 PM    C
                             2     8/20/2012 1:00 PM    A

結果は次のようになります。

TABLE C                      
ID    TIMESTMP             VALUE
1     8/31/2012 2:00 PM    B
2     8/29/2012 3:00 PM    A      
3     7/04/2012 5:00 AM    null  

テーブルBで、最大タイムスタンプがまだ<テーブルAのタイムスタンプである対応するレコードを検索したい。一致するID(外部結合)がない場合、またはBにタイムスタンプがない場合<Aのタイムスタンプである必要があります。 nullを返します。

ありがとう!

アップデート

Gordon Linoffによって提案されたlead()を使用して行った解決策は次のとおりです。

SELECT b.value, a.*
  FROM table_a a
  LEFT OUTER JOIN (
     SELECT id, timestmp, 
            lead(timestmp) over(PARTITION BY id ORDER BY timestmp) AS next_timestmp,
            value FROM table_b
    ) b
  ON a.id = b.id
  AND (a.timestmp >= b.timestmp AND (a.timestmp < b.timestmp OR b.timestmp IS NULL))
4

4 に答える 4

2
with cte as
(
select *,
    ROW_NUMBER() over (partition by id order by timestmp) as rn
from TableB 
)

    select
        v.id, v.timestmp, value

    from
    (       
    select a.id, a.timestmp, MAX(isnull(rn,1) )rn
    from TableA a
        left join cte
        on a.id = cte.id
        and a.timestmp>cte.timestmp
    group by a.id, a.timestmp
    ) v
        left join cte
        on v.id = cte.id
        and v.rn = cte.rn
    order by v.id;
于 2012-08-31T14:39:34.990 に答える
1

これがSQLサーバーの場合、これは外部適用で実現できると思います

すなわち

SELECT A.id, A.timestmp, B.value FROM A OUTER APPLY (SELECT TOP 1 value FROM B WHERE id = A.id AND timesmtp < A.timestmp ORDER BY timesmtp DESC) B
于 2012-08-31T14:38:09.287 に答える
1

これは結合として表現できますが、「=」は使用しません。ただし、役立つのは、各行に次のタイムスタンプを付けることです。ここで、lead()関数が役に立ちます。

select a.id, a.timestmp, b.value
from A left outer join
     (select b.*,
             lead(timesmtp) over (partition by id order by timesmtp) as nextTS
      from B
    ) b
    on a.id = b.id and
       a.timestmp >= b.timesmtp and
       a.timestmp < coalesce(nextTS, a.timestmp)
于 2012-08-31T14:39:51.373 に答える
0
select t.ID, t.Timestamp,B.Value
from
(
select A.ID, A.Timestamp, (SELECT max(B.TimeStamp) 
     FROM B where (B.Timestamp<A.Timestamp) and (B.id=A.Id)
   ) max_date

from A
  ) t
left join B on (t.max_date=B.TimeStamp) and (t.Id=B.ID)
于 2012-08-31T14:52:59.737 に答える