You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在SQL中基于日期映射匹配历史数据的对应Stage值?

问题:匹配时间点对应的历史Stage值,保留Table A全部数据

Table A

IDPoint_dateTENANT
1143968451/5/21vp.com
1143968451/5/21vp.com
1143968451/8/21vp.com
1143968451/8/21vp.com
1143968451/8/21vp.com
1143968451/8/21vp.com
1143968453/30/21vp.com
1143968454/5/21vp.com
7563927415/27/21vp.com
7563927417/22/21vp.com
7563927417/22/21vp.com
75639274111/29/21vp.com
75639274111/29/21vp.com
75639274112/27/21vp.com
7563927411/24/22vp.com
7563927411/28/22vp.com
7563927411/29/22vp.com
7563927412/6/22vp.com
7563927412/8/22vp.com
7563927412/10/22vp.com
7563927412/10/22vp.com
7563927412/10/22vp.com
7563927412/14/22vp.com
7563927412/18/22vp.com
7563927412/18/22vp.com
7563927412/23/22vp.com
7563927412/23/22vp.com
7563927413/6/22vp.com
7563927413/10/22vp.com
7563927413/10/22vp.com

Table B

IDTENANTSTAGEChange_date
114396845vp.comstage1_Newbi12/14/20
114396845vp.comstage3_B_Tool1/6/21
756392741vp.comstage14/30/21
756392741vp.comstage5_per_Tool7/23/21
756392741vp.comstage6_Unbonused2/15/22
756392741vp.comstage12_PreMate4/9/22
756392741vp.comstage13_Respe7/18/22

期望结果

IDPoint_dateTENANTSTAGE
1143968451/5/21vp.comstage1_Newbi
1143968451/5/21vp.comstage1_Newbi
1143968451/8/21vp.comstage3_B_Tool
1143968451/8/21vp.comstage3_B_Tool
1143968451/8/21vp.comstage3_B_Tool
1143968451/8/21vp.comstage3_B_Tool
1143968453/30/21vp.comstage3_B_Tool
1143968454/5/21vp.comstage3_B_Tool
7563927415/27/21vp.comstage1
7563927417/22/21vp.comstage1
7563927417/22/21vp.comstage1
75639274111/29/21vp.comstage5_per_Tool
75639274111/29/21vp.comstage5_per_Tool
75639274112/27/21vp.comstage5_per_Tool
7563927411/24/22vp.comstage5_per_Tool
7563927411/28/22vp.comstage5_per_Tool
7563927411/29/22vp.comstage5_per_Tool
7563927412/6/22vp.comstage5_per_Tool
7563927412/8/22vp.comstage5_per_Tool
7563927412/10/22vp.comstage5_per_Tool
7563927412/10/22vp.comstage5_per_Tool
7563927412/10/22vp.comstage5_per_Tool
7563927412/14/22vp.comstage6_Unbonused
7563927412/18/22vp.comstage6_Unbonused
7563927412/18/22vp.comstage6_Unbonused
7563927412/23/22vp.comstage6_Unbonused
7563927412/23/22vp.comstage6_Unbonused
7563927413/6/22vp.comstage6_Unbonused
7563927413/10/22vp.comstage6_Unbonused
7563927413/10/22vp.comstage6_Unbonused

需求说明

保留Table A的全部数据,新增来自Table B的Stage列。匹配规则为:根据Table A的Point_date,取Table B中对应ID、TENANT下该时间点的历史Stage值(即该Point_date之前或当天最近一次变更后的Stage)。

解决方案

方法1:使用LATERAL JOIN(适用于PostgreSQL、SQL Server、MySQL 8.0+)

这种写法效率较高,针对Table A的每条记录,精准匹配符合条件的最新Stage:

SELECT 
    a.ID,
    a.Point_date,
    a.TENANT,
    b.STAGE
FROM 
    TableA a
LEFT JOIN LATERAL (
    SELECT STAGE
    FROM TableB b
    WHERE b.ID = a.ID 
      AND b.TENANT = a.TENANT 
      AND b.Change_date <= a.Point_date
    ORDER BY b.Change_date DESC
    LIMIT 1
) b ON TRUE
ORDER BY 
    a.ID, a.Point_date;

方法2:使用窗口函数(通用支持窗口函数的数据库)

先对Table B的记录按ID、TENANT分组并按变更日期倒序排名,再关联Table A筛选出符合条件的最新记录:

WITH ranked_stages AS (
    SELECT 
        ID,
        TENANT,
        STAGE,
        Change_date,
        ROW_NUMBER() OVER (PARTITION BY ID, TENANT ORDER BY Change_date DESC) AS rn
    FROM TableB
)
SELECT 
    a.ID,
    a.Point_date,
    a.TENANT,
    rs.STAGE
FROM TableA a
LEFT JOIN ranked_stages rs 
    ON a.ID = rs.ID 
    AND a.TENANT = rs.TENANT 
    AND rs.Change_date <= a.Point_date
    AND rs.rn = 1
ORDER BY a.ID, a.Point_date;

注意事项

  • 确保Point_date和Change_date字段为日期类型,如果是字符串格式,需要先转换为日期类型再比较,避免字符串排序导致的错误。例如:
    • MySQL:STR_TO_DATE(Point_date, '%m/%d/%y')
    • PostgreSQL:TO_DATE(Point_date, 'MM/DD/YY')
    • SQL Server:CAST(Point_date AS DATE)
  • 如果存在多个相同ID、TENANT且Change_date相同的记录,ROW_NUMBER()会随机取一条,若想保留所有符合条件的记录,可替换为RANK()。

内容的提问来源于stack exchange,提问作者SAugustine

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 07:48:16