如何通过SQL将AvgExpected与AvgNow合并为新列并关联标识
解决方案:将多列统计结果转置合并为单列并标注来源
要实现将AvgExpected和AvgNow两列合并为单个Avg列,同时拼接Name标注数据来源的需求,最直接的方式是使用UNION ALL拆分并合并数据,以下是两种优化后的SQL实现:
方式一:使用CTE复用分组逻辑(推荐)
此方式通过公共表表达式(CTE)先完成原有的分组统计,避免重复编写查询逻辑,提升代码可读性和维护性:
WITH grouped_data AS ( SELECT EndTime, AVG(E_AVG) AS AvgExpected, AVG(Avg_Now) AS AvgNow, Name FROM table1 WHERE Name = 'Name1' AND EndTime BETWEEN '2022-12-04 07:17' AND '2022-12-04 15:17' GROUP BY EndTime, Name ) -- 提取AvgNow数据并标注来源 SELECT EndTime, AvgNow AS Avg, CONCAT(Name, ' AvgNow') AS Name FROM grouped_data UNION ALL -- 提取AvgExpected数据并标注来源 SELECT EndTime, AvgExpected AS Avg, CONCAT(Name, ' AvgExpected') AS Name FROM grouped_data -- 按时间排序,同时确保AvgNow记录排在前面 ORDER BY EndTime, CASE WHEN Name LIKE '%AvgNow' THEN 1 ELSE 2 END;
方式二:直接使用UNION ALL(适合简单场景)
如果不支持CTE(如部分旧版本数据库),可以直接重复原查询逻辑:
-- 提取AvgNow数据 SELECT EndTime, AvgNow AS Avg, CONCAT(Name, ' AvgNow') AS Name FROM ( SELECT EndTime,AVG(E_AVG) AS AvgExpected,AVG(Avg_Now) AS AvgNow,Name FROM table1 WHERE Name='Name1' AND EndTime BETWEEN '2022-12-04 07:17' AND '2022-12-04 15:17' GROUP BY EndTime, Name ) AS subquery UNION ALL -- 提取AvgExpected数据 SELECT EndTime, AvgExpected AS Avg, CONCAT(Name, ' AvgExpected') AS Name FROM ( SELECT EndTime,AVG(E_AVG) AS AvgExpected,AVG(Avg_Now) AS AvgNow,Name FROM table1 WHERE Name='Name1' AND EndTime BETWEEN '2022-12-04 07:17' AND '2022-12-04 15:17' GROUP BY EndTime, Name ) AS subquery ORDER BY EndTime, CASE WHEN Name LIKE '%AvgNow' THEN 1 ELSE 2 END;
关键说明:
- 使用
UNION ALL而非UNION:因为两部分结果不会有重复行,UNION ALL的执行效率更高 - 字符串拼接:使用
CONCAT函数实现名称拼接(若使用SQL Server,也可直接用+;Oracle用||) - 排序规则:通过
CASE语句确保AvgNow的记录排在AvgExpected之前,完全匹配你期望的输出顺序
内容的提问来源于stack exchange,提问作者abababa
相关产品推荐
相关产品推荐

