SQL Server查询需求:筛选值有变化的数据,排除无变更记录
SQL Server 查询方案:过滤无实际变更的循环记录
需求分析
需要在20230101至20230110日期范围内,排除那些id对应的数值来回循环、整体无变化的记录(如pers从400→600再回到400,incl从850→900再回到850),仅保留有真实数值变化的id的全部记录。
核心逻辑
判断每个id的**初始值(该id最早记录的before字段)和最终值(该id最晚记录的after字段)**是否相等:
- 若相等:说明该id的数值只是来回循环,无实际变更,排除所有相关记录
- 若不等:说明该id的数值有真实变化,保留所有相关记录
查询语句
假设你的数据表名为your_table,执行以下SQL:
WITH id_change_status AS ( SELECT id, FIRST_VALUE(before) OVER (PARTITION BY id ORDER BY date) AS initial_value, LAST_VALUE(after) OVER (PARTITION BY id ORDER BY date ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) AS final_value FROM your_table WHERE date BETWEEN '20230101' AND '20230110' ), valid_ids AS ( SELECT DISTINCT id FROM id_change_status WHERE initial_value != final_value ) SELECT t.id, t.date, t.before, t.after FROM your_table t JOIN valid_ids v ON t.id = v.id WHERE t.date BETWEEN '20230101' AND '20230110' ORDER BY t.date;
语句说明
id_change_statusCTE:为每个id的每条记录计算初始值(最早的before)和最终值(最晚的after),使用窗口函数FIRST_VALUE和LAST_VALUE实现,PARTITION BY id确保按id分组计算,ORDER BY date保证取到正确的时间顺序值。valid_idsCTE:筛选出初始值与最终值不相等的id,这些是有真实变化的有效id。- 最终查询:关联原表与有效id列表,仅保留日期范围内的有效记录,并按日期排序。
为什么min/max方案不适用
直接使用MIN(before)或MAX(after)只能获取字段的极值,无法反映数值的变化路径。比如pers的before最小值是400、最大值是600,但最终值又回到了初始的400,这种循环变化无法通过极值判断,而通过初始值和最终值的对比可以精准识别这类无意义的循环。
内容的提问来源于stack exchange,提问作者newbie.naina
相关产品推荐
相关产品推荐

