我试图在两个表之间写一个连接,其中左表中的日期值落入右表的一个时隙。所以,例如,如果我有:
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))
答案 0 :(得分: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;
答案 1 :(得分:1)
如果这是sql server我相信这可以通过外部应用
来实现即
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
答案 2 :(得分: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)
答案 3 :(得分: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)