在最近的日期和按分区加入
Join on most recent date and by partition
我有两张桌子,
点击次数:
user date
a 01/10/2021
a 02/10/2021
a 03/10/2021
b 27/09/2021
c 08/10/2021
c 13/10/2021
和细分:
user date segment
a 26/09/2021 1
a 27/09/2021 1
a 03/10/2021 2
c 01/10/2021 5
c 10/10/2021 6
我想将细分加入点击以识别每个用户在给定点击日期的最新细分。所以正确的输出应该是这样的:
user date segment
a 01/10/2021 1
a 02/10/2021 1
a 03/10/2021 2
b 27/09/2021
c 08/10/2021 5
c 13/10/2021 6
我尝试了以下但得到错误 'this type of correlated subquery pattern is not supported due to internal error'
select *,
(select top 1 segment
from b
where
b.date <= a.date
ORDER BY ROW_NUMBER() OVER(PARTITION BY b.id ORDER BY b.date DESC)) as segment_lookup
from a;
非常感谢找到最佳方法的任何帮助。提前致谢
你没有提到数据库,所以我假设它是 SQL 服务器。
此外,第一个 table 似乎没有键,因此下面的查询使用 (user
, date
) 作为键。
你可以这样做:
select *
from (
select
c.*, s.segment,
row_number() over(partition by c.u, c.d order by s.d desc) as rn
from clicks c
left join segment s on s.u = c.u and c.d >= s.d
) x
where rn = 1
结果:
u d segment rn
-- ----------- -------- --
a 2021-10-01 1 1
a 2021-10-02 1 1
a 2021-10-03 2 1
b 2021-09-27 1
c 2021-10-08 5 1
c 2021-10-13 6 1
参见 db<>fiddle 1 中的 运行 示例。
或者,您可以使用理论上性能更好的横向连接。
编辑:按要求添加横向连接
带有横向连接的查询可以采用以下形式:
select
c.*, s.segment
from clicks c
outer apply (
select top 1 * from segment s where s.u = c.u and c.d >= s.d
order by s.d desc
) s
结果:
u d segment
-- ----------- -------
a 2021-10-01 1
a 2021-10-02 1
a 2021-10-03 2
b 2021-09-27
c 2021-10-08 5
c 2021-10-13 6
参见 db<>fiddle 2 中的 运行 示例。
如果创建了索引 segment (u, d)
,横向连接可能会非常高效。
我有两张桌子, 点击次数:
user date
a 01/10/2021
a 02/10/2021
a 03/10/2021
b 27/09/2021
c 08/10/2021
c 13/10/2021
和细分:
user date segment
a 26/09/2021 1
a 27/09/2021 1
a 03/10/2021 2
c 01/10/2021 5
c 10/10/2021 6
我想将细分加入点击以识别每个用户在给定点击日期的最新细分。所以正确的输出应该是这样的:
user date segment
a 01/10/2021 1
a 02/10/2021 1
a 03/10/2021 2
b 27/09/2021
c 08/10/2021 5
c 13/10/2021 6
我尝试了以下但得到错误 'this type of correlated subquery pattern is not supported due to internal error'
select *,
(select top 1 segment
from b
where
b.date <= a.date
ORDER BY ROW_NUMBER() OVER(PARTITION BY b.id ORDER BY b.date DESC)) as segment_lookup
from a;
非常感谢找到最佳方法的任何帮助。提前致谢
你没有提到数据库,所以我假设它是 SQL 服务器。
此外,第一个 table 似乎没有键,因此下面的查询使用 (user
, date
) 作为键。
你可以这样做:
select *
from (
select
c.*, s.segment,
row_number() over(partition by c.u, c.d order by s.d desc) as rn
from clicks c
left join segment s on s.u = c.u and c.d >= s.d
) x
where rn = 1
结果:
u d segment rn
-- ----------- -------- --
a 2021-10-01 1 1
a 2021-10-02 1 1
a 2021-10-03 2 1
b 2021-09-27 1
c 2021-10-08 5 1
c 2021-10-13 6 1
参见 db<>fiddle 1 中的 运行 示例。
或者,您可以使用理论上性能更好的横向连接。
编辑:按要求添加横向连接
带有横向连接的查询可以采用以下形式:
select
c.*, s.segment
from clicks c
outer apply (
select top 1 * from segment s where s.u = c.u and c.d >= s.d
order by s.d desc
) s
结果:
u d segment
-- ----------- -------
a 2021-10-01 1
a 2021-10-02 1
a 2021-10-03 2
b 2021-09-27
c 2021-10-08 5
c 2021-10-13 6
参见 db<>fiddle 2 中的 运行 示例。
如果创建了索引 segment (u, d)
,横向连接可能会非常高效。