MS SQL日期格式化与事件摘要排序查询问题求助
MS SQL 查询问题解决方案:日期格式化、事件拼接及月维度最大值处理
1. 日期字段转YYYY-MM格式
在MS SQL里,有两种可靠的实现方式:
- 全版本兼容:用
CONVERT函数截取前7位(格式码120对应YYYY-MM-DD):CONVERT(varchar(7), date_col, 120) AS month_year - SQL Server 2012+适用:用
FORMAT函数,注意月份必须用大写MM(小写mm是分钟,这大概率是你之前出错的原因):FORMAT(date_col, 'yyyy-MM') AS month_year
2. 拼接top_event_summary(按绝对值降序)
需要先把sell和buy转成行数据,排序后再拼接。推荐用STRING_AGG(SQL Server 2017+)实现:
SELECT STRING_AGG(CONCAT('[', event_name, '] : [', value, ']'), ' *** ') AS top_event_summary FROM ( SELECT event_name, value, ABS(value) AS abs_value FROM your_table CROSS APPLY (VALUES ('sell', sell), ('buy', buy)) AS unpivoted(event_name, value) ORDER BY abs_value DESC OFFSET 0 ROWS FETCH NEXT 2 ROWS ONLY -- 取绝对值最大的前2个事件 ) AS ranked_events
如果是SQL Server 2016及以下版本,用STUFF+FOR XML PATH替代:
SELECT STUFF(( SELECT ' *** ' + CONCAT('[', event_name, '] : [', value, ']') FROM ( SELECT event_name, value, ABS(value) AS abs_value FROM your_table CROSS APPLY (VALUES ('sell', sell), ('buy', buy)) AS unpivoted(event_name, value) ORDER BY abs_value DESC OFFSET 0 ROWS FETCH NEXT 2 ROWS ONLY ) AS ranked_events FOR XML PATH(''), TYPE ).value('.', 'varchar(max)'), 1, 4, '') AS top_event_summary
3. 结合GROUP BY、MAX实现月维度局部最大值处理
按月份分组,取每个月绝对值最高的事件拼接成摘要,同时统计月度最大绝对值:
WITH monthly_events AS ( SELECT CONVERT(varchar(7), date_col, 120) AS month_year, event_name, value, ABS(value) AS abs_value, -- 按月份分组,给事件按绝对值降序排名 ROW_NUMBER() OVER (PARTITION BY CONVERT(varchar(7), date_col, 120) ORDER BY ABS(value) DESC) AS rn FROM your_table CROSS APPLY (VALUES ('sell', sell), ('buy', buy)) AS unpivoted(event_name, value) ) SELECT month_year, STRING_AGG(CONCAT('[', event_name, '] : [', value, ']'), ' *** ') AS top_event_summary, MAX(abs_value) AS monthly_max_abs_value FROM monthly_events WHERE rn <= 2 -- 保留每个月绝对值最高的前2个事件 GROUP BY month_year ORDER BY month_year
关键踩坑提示
- 用
FORMAT时必须区分MM(月份)和mm(分钟),这是日期格式化常见错误; - 拼接事件前必须先把列转成行,否则无法按绝对值排序;
- 大数据量场景下,
CONVERT做日期分组比FORMAT性能更高。
内容的提问来源于stack exchange,提问作者Gery
相关产品推荐
相关产品推荐

