SQL Server中基于前一日数据填充缺失Rating值的查询实现
用SQL填充Rating列空值(向前结转前一行有效值)
这是一个很常见的**向前填充(forward fill)**需求,核心是把Rating列的空值替换为它紧邻的上一行非空值。不同SQL数据库的实现方式略有差异,我给你整理了几种主流场景的解决方案:
1. 支持窗口函数的数据库(MySQL 8.0+、PostgreSQL、SQL Server 2012+、Oracle 11g+)
这类数据库可以借助窗口函数来实现,最通用的写法是通过分组标记,把连续的空值和前面的非空值归为一组,再取组内的有效值:
SELECT id, -- 替换成你的其他实际列名 column1, column2, LAST_VALUE(Rating) OVER ( PARTITION BY grp ORDER BY id ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) AS filled_Rating FROM ( SELECT *, -- 生成分组:每遇到非空的Rating,分组号加1,连续空值会和前面的非空值同组 COUNT(Rating) OVER (ORDER BY id) AS grp FROM your_table -- 替换成你的表名 ) AS sub_query;
针对不同数据库的简化写法
MySQL 8.0.22+:支持
IGNORE NULLS参数,可以直接跳过空值取最后一个有效值,无需分组:SELECT id, column1, column2, LAST_VALUE(Rating IGNORE NULLS) OVER ( ORDER BY id ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) AS filled_Rating FROM your_table;PostgreSQL:可以用
MAX窗口函数替代LAST_VALUE,因为同一分组内的MAX(Rating)就是唯一的非空值:SELECT id, column1, column2, MAX(Rating) OVER (PARTITION BY grp ORDER BY id) AS filled_Rating FROM ( SELECT *, COUNT(Rating) OVER (ORDER BY id) AS grp FROM your_table ) AS sub_query;
2. 不支持窗口函数的老版本数据库(比如MySQL 5.x)
这类数据库需要使用用户变量来实现向前结转:
SELECT id, column1, column2, -- 如果当前Rating非空则更新变量,否则沿用变量的上一个值 @prev_rating := IF(Rating IS NOT NULL, Rating, @prev_rating) AS filled_Rating FROM your_table, -- 初始化变量为NULL (SELECT @prev_rating := NULL) AS init_var -- 必须按正确的顺序排序,保证"紧邻前一行"的逻辑正确 ORDER BY id;
重要注意事项
- 请替换代码中的
your_table、id、column1/column2为你的实际表名、排序列和其他列名 - 排序列(比如
id)必须能保证行的顺序符合你对"紧邻前一行"的定义,如果是按时间排序就换成时间列 - 如果需要按某个维度分组填充(比如每个用户单独处理Rating),需要在窗口函数的
PARTITION BY中加入分组列(比如PARTITION BY user_id, grp),变量写法则需要按分组列+排序列排序,并处理分组切换时的变量重置。
内容的提问来源于stack exchange,提问作者Preedhi
相关产品推荐
相关产品推荐

