如何将数据库查询的垂直纵向结果转换为横向水平格式展示
行转列(纵向转横向)实现方案
需求说明:将按ITEM分组重复的纵向ALTERNATE记录,转换为每个ITEM对应一行、每个ALTERNATE值占单独列的横向结构,单ITEM最多支持20+条ALTERNATE记录。
通用实现思路(所有数据库通用)
核心逻辑分为两步:
- 第一步:给每个ITEM下的ALTERNATE记录按顺序生成序号(1、2、3...N,N最大不超过你单ITEM的最大记录数,比如20)
- 第二步:按ITEM、DESCRIPTION分组,通过条件聚合把不同序号的ALTERNATE值放到对应的列
常用数据库具体实现代码
MySQL 8.0+/MariaDB
WITH numbered_data AS ( SELECT ITEM, DESCRIPTION, ALTERNATE, -- 给同ITEM下的替代编码按顺序编序号 ROW_NUMBER() OVER (PARTITION BY ITEM ORDER BY ALTERNATE) AS rn FROM 你的原始表名 ) SELECT ITEM, DESCRIPTION, MAX(CASE WHEN rn = 1 THEN ALTERNATE END) AS ALTERNATE, MAX(CASE WHEN rn = 2 THEN ALTERNATE END) AS ALTERNATE1, MAX(CASE WHEN rn = 3 THEN ALTERNATE END) AS ALTERNATE2, -- 单ITEM最多有多少条记录就往后加多少行,比如最多20条就写到rn=20 MAX(CASE WHEN rn = 20 THEN ALTERNATE END) AS ALTERNATE19 FROM numbered_data GROUP BY ITEM, DESCRIPTION ORDER BY ITEM;
PostgreSQL
可以直接用内置的crosstab行转列函数,提前扩展tablefunc插件即可:
-- 先安装扩展(仅需执行一次) CREATE EXTENSION IF NOT EXISTS tablefunc; -- 行转列查询 SELECT * FROM crosstab( 'SELECT ITEM, DESCRIPTION, ALTERNATE FROM 你的原始表名 ORDER BY 1,2', 'SELECT generate_series(1,20)' -- 对应最多20个ALTERNATE值 ) AS ct ( ITEM INT, DESCRIPTION VARCHAR(255), ALTERNATE INT, ALTERNATE1 INT, -- 按需补全到ALTERNATE19即可 ALTERNATE19 INT );
Oracle
直接用PIVOT关键字实现:
SELECT * FROM ( SELECT ITEM, DESCRIPTION, ALTERNATE, ROW_NUMBER() OVER (PARTITION BY ITEM ORDER BY ALTERNATE) rn FROM 你的原始表名 ) PIVOT ( MAX(ALTERNATE) FOR rn IN ( 1 AS ALTERNATE, 2 AS ALTERNATE1, 3 AS ALTERNATE2, -- 补全到20即可 20 AS ALTERNATE19 ) ) ORDER BY ITEM;
如果使用的数据库不支持以上语法,也可以用子查询嵌套的方式手动拼接条件聚合逻辑,效果完全一致。
内容的提问来源于stack exchange,提问作者Efren Caballes
相关产品推荐
相关产品推荐

