SQL Server如何筛选最新日期记录并按meta分组聚合Code列表
SQL Server 实现方案
核心处理逻辑对齐需求规则,提前过滤无效数据减少计算量,避免不必要的字段拆分操作:
- 直接排除
date为1900年且meta为NULL的历史旧记录,这类数据不参与后续计算 - 如果
date字段是DATE/DATETIME类型,直接做大小比较即可,天然按年→月→日优先级判断日期先后,不需要单独拆分年、月、日字段比对,性能更高 - 统一以
meta_ID作为分组维度,和业务中「同一meta_ID对应多条不同日期记录」的规则对齐
高版本实现(SQL Server 2017 及以上版本,支持STRING_AGG函数)
用窗口函数直接标记分组内最新日期,再按分组拼接Code,逻辑简单执行效率高:
WITH valid_data AS ( SELECT Code, meta, meta_ID, date, MAX(date) OVER (PARTITION BY meta_ID) AS group_latest_date FROM 替换为你的实际业务表名 -- 过滤指定的无效旧记录 WHERE NOT (DATEPART(YEAR, date) = 1900 AND meta IS NULL) ) SELECT vd.Code, vd.meta, vd.meta_ID, -- 同组Code按逗号拼接,可自行修改分隔符 STRING_AGG(vd.Code, ',') WITHIN GROUP (ORDER BY vd.Code) AS list_Code, vd.date FROM valid_data vd -- 只保留分组下最新日期对应的有效记录 WHERE vd.date = vd.group_latest_date GROUP BY vd.Code, vd.meta, vd.meta_ID, vd.date
低版本兼容实现(SQL Server 2016 及以下版本,无STRING_AGG函数)
用FOR XML PATH语法实现字符串拼接,逻辑和高版本完全一致:
WITH valid_data AS ( SELECT Code, meta, meta_ID, date, MAX(date) OVER (PARTITION BY meta_ID) AS group_latest_date FROM 替换为你的实际业务表名 WHERE NOT (DATEPART(YEAR, date) = 1900 AND meta IS NULL) ), latest_records AS ( SELECT * FROM valid_data WHERE date = group_latest_date ) SELECT t1.Code, t1.meta, t1.meta_ID, STUFF( (SELECT ',' + t2.Code FROM latest_records t2 WHERE t2.meta_ID = t1.meta_ID ORDER BY t2.Code FOR XML PATH(''), TYPE ).value('.', 'NVARCHAR(MAX)'), 1,1,'' ) AS list_Code, t1.date FROM latest_records t1
注意事项
- 代码中
替换为你的实际业务表名位置改成真实表名即可直接运行 - Code拼接默认使用逗号作为分隔符,需要其他分隔符直接替换对应位置的符号即可
- 如果确认1900年的所有记录都是要剔除的旧数据(不存在meta非空的有效记录),可以把过滤条件简化为
WHERE DATEPART(YEAR, date) <> 1900,查询速度会更快 - 如果业务上同一meta_ID、同一最新日期存在多条不同Code的记录,上述脚本会保留所有符合要求的记录,且每条记录的
list_Code字段都会包含该分组下所有有效Code值,完全匹配输出字段要求
内容的提问来源于stack exchange,提问作者ch hach
相关产品推荐
相关产品推荐

