SQL查询需求:用Table B最新数据填充关联后的Sales空值
问题解决:按日期关联后填充最新历史Sales值
表结构与场景说明
假设我们有两张表:
- TableA:存储2023年6月1日至30日
Product A的每日活动记录,字段为activity_day(日期)、product(产品名称)。 - TableB:存储产品的销售评估记录,字段为
evaluation_day(评估日期)、product(产品名称)、sales(销售额),仅包含若干离散日期的记录。
需求是将两张表按日期和产品关联后,用TableB中当前activity_day之前最新的sales值填充空值(例如2023-06-03需使用2023-05-29的66)。
通用SQL方案(支持窗口函数的数据库:MySQL 8+、PostgreSQL、SQL Server等)
WITH RankedSales AS ( SELECT a.activity_day, a.product, b.sales, -- 按日期倒序排名,每组内排名1的是最新记录 ROW_NUMBER() OVER ( PARTITION BY a.activity_day, a.product ORDER BY b.evaluation_day DESC ) AS rn FROM TableA a LEFT JOIN TableB b ON a.product = b.product AND b.evaluation_day <= a.activity_day ) SELECT activity_day, product, -- 提取每组内排名第一的sales值 MAX(CASE WHEN rn = 1 THEN sales END) AS filled_sales FROM RankedSales GROUP BY activity_day, product ORDER BY activity_day;
逻辑说明:
- 先将TableA与TableB按产品关联,仅保留TableB中日期≤当前activity_day的记录;
- 用
ROW_NUMBER()按activity_day和product分组,对每组内的TableB记录按evaluation_day倒序排名; - 最后分组筛选出排名为1的sales值,即为当前日期需要填充的最新历史销售额。
高效优化方案(PostgreSQL/SQL Server专属)
如果使用PostgreSQL,可通过LATERAL JOIN实现更高效的单条记录匹配:
SELECT a.activity_day, a.product, b.sales AS filled_sales FROM TableA a LEFT JOIN LATERAL ( -- 直接查询当前日期前的最新sales记录 SELECT sales FROM TableB b WHERE b.product = a.product AND b.evaluation_day <= a.activity_day ORDER BY b.evaluation_day DESC LIMIT 1 ) b ON true ORDER BY a.activity_day;
如果是SQL Server,替换为OUTER APPLY即可:
SELECT a.activity_day, a.product, b.sales AS filled_sales FROM TableA a OUTER APPLY ( SELECT TOP 1 sales FROM TableB b WHERE b.product = a.product AND b.evaluation_day <= a.activity_day ORDER BY b.evaluation_day DESC ) b ORDER BY a.activity_day;
逻辑说明:
对TableA的每一行数据,通过子查询直接定位到对应产品、日期不晚于当前activity_day的最新sales记录,避免了全局分组排序,性能更优,尤其适合TableB数据量较大的场景。
内容的提问来源于stack exchange,提问作者puneeth
相关产品推荐
相关产品推荐

