在最近的日期和按分区加入

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),横向连接可能会非常高效。