如何在SQL Pivot中同时使用多个聚合函数生成指定格式结果
问题描述
我有一张存储模拟数据的表escen,字段说明如下:
date_data:模拟执行日期ID/Name:用户标识Scenery:场景类型N Simu:模拟总次数(每个场景下固定为1000次)Simul:单次模拟的序号Date:模拟的未来日期Value:随机模拟值
现有SQL仅能计算Value的平均值并按未来日期T透视,但我需要为每个ID、每个未来日期同时计算平均值(avg)、最大值(max)、最小值(min)、标准差(stddev),并将这四种聚合结果整合到同一输出中,通过Function列标识聚合类型,而非生成4个独立结果。
现有SQL(仅计算平均值):
select * from (select date_data,id, name, scenery, (extract(month from date)-extract(month from data_date))+12*(extract(year from date)-extract(year from data_date)) as T, value from escen where date_data = '30/09/2022' and scenario in ('BASE') ) pivot ( avg(value) for T between 0 and 120 order by 1, 2, 3, 4;
表数据示例:
| date_data | ID | Name | Scenery | N Simu | Simul | Date | Value |
|---|---|---|---|---|---|---|---|
| 30/09/22 | 1 | A | Base | 1000 | 1 | 30/09/28 | 0,0397 |
| 30/09/22 | 1 | A | Base | 1000 | 2 | 30/09/28 | -0,069 |
期望输出格式:
| date_data | Function | ID | Name | Scenery | 30/09/28 | 31/10/28 |
|---|---|---|---|---|---|---|
| 30/09/22 | Average | 1 | A | Base | avg(value)结果 | avg(value)结果 |
| 30/09/22 | Minimum | 1 | A | Base | min(value)结果 | min(value)结果 |
| 30/09/22 | Maximum | 1 | A | Base | max(value)结果 | max(value)结果 |
| 30/09/22 | Stdev | 1 | A | Base | std(value)结果 | std(value)结果 |
| ... | ... | ... | ... | ... | ... | ... |
解决方案SQL
以下SQL基于Oracle语法实现需求,先分组计算聚合值,再通过UNPIVOT将聚合列转为行,最后通过PIVOT将未来日期转为列:
SELECT date_data, function_type, id, name, scenery, "30/09/28", "31/10/28" FROM ( -- 第一步:按维度分组,计算四个聚合值 SELECT date_data, id, name, scenery, "Date" AS future_date, AVG(value) AS avg_val, MAX(value) AS max_val, MIN(value) AS min_val, STDDEV(value) AS stddev_val FROM escen WHERE date_data = '30/09/2022' AND scenery = 'BASE' GROUP BY date_data, id, name, scenery, "Date" ) -- 第二步:将四个聚合列转为行,生成function_type列 UNPIVOT ( agg_value FOR function_type IN ( avg_val AS 'Average', max_val AS 'Maximum', min_val AS 'Minimum', stddev_val AS 'Stdev' ) ) -- 第三步:将未来日期转为列 PIVOT ( MAX(agg_value) FOR future_date IN ( '30/09/28' AS "30/09/28", '31/10/28' AS "31/10/28" -- 可添加更多需要的日期 ) ) ORDER BY id, function_type;
说明
- 分组聚合:先按
date_data、id、name、scenery、Date分组,计算每个组的四个聚合值,确保每个ID的每个未来日期都有对应的统计结果。 - UNPIVOT转换:将四个聚合列(avg_val、max_val等)转为行,同时用
function_type标识聚合类型,实现把不同聚合结果放到同一列的效果。 - PIVOT转换:将未来日期
future_date转为列,每个日期作为单独的列展示对应聚合值,匹配期望的输出格式。 - 动态日期处理:如果未来日期不固定,可使用动态SQL生成
PIVOT中的日期列,避免手动维护。
内容的提问来源于stack exchange,提问作者Guillem
相关产品推荐
相关产品推荐

