这是东西。我有这两个表:
表A:
id col1 date_x
A xxxx 2020-02-02
B yyyy 2020-02-02
C zzzz 2020-02-02
表B
id col2 date_y
A yyyy 2020-01-02
A yyyy 2020-02-02
A yyyy 2020-03-02
我想在date_y尽可能高的时候带上col2,但必须低于date_x。
这就是我所做的:
select *,
(
select top 1 col2
from table_B
where table_B.date_y < a.date_x
and table_B.id = a.id
) as col2
from table_A a
现在,我也想带date_y来进行验证。
做到这一点的最佳方法是什么?我考虑过要创建另一个(选择前1个...),但这似乎效率很低。另一个联接也将效率低下。
答案 0 :(得分:1)
您可以根据自己的条件联接表,并使用MAX()
和FIRST_VALUE()
窗口函数来获取date_y
和col2
的值:
select distinct a.*,
first_value(b.col2) over (partition by a.id order by b.date_y desc, b.col2) col2,
max(b.date_y) over (partition by a.id) date_y
from tableA a left join tableB b
on b.id = a.id and b.date_y < a.date_x
如果只想从2个表中匹配行,则可以将LEFT
联接更改为INNER
联接。
请参见demo。
答案 1 :(得分:0)
您使用相关子查询的方法是可以的-Redshift支持top
(尽管我更喜欢limit
,在其他数据库中更受支持)。
但是,子查询中缺少一个order by
子句-如果没有子句,则会从满足where
子句的行中得到一个无法预测的行。
我建议:
select
a.*,
(
select col2
from table_B b
where b.date_y < a.date_x and b.id = a.id
order by b.date_y desc
limit 1
) as col2
from table_A a
为提高性能,请考虑在table_B(id, date_y, col2)
上建立索引。