PostgreSQL中如何将多行存储的数据表转换为单行多列的宽表?
行转列(EAV模型转宽表)SQL实现方案
你当前的表是典型的键值对属性存储结构(EAV模型),要转成单行多列的宽表可以用以下几种方案实现:
通用兼容方案(所有关系型数据库可用)
不依赖数据库专属语法,兼容性最强,核心是用CASE WHEN匹配规格后聚合合并行:
SELECT product_id, MAX(CASE WHEN spec = 'speed' THEN value END) AS speed, MAX(CASE WHEN spec = 'weight' THEN value END) AS weight, MAX(CASE WHEN spec = 'power' THEN value END) AS power, MAX(CASE WHEN spec = 'autonomy' THEN value END) AS autonomy FROM 你的表名 GROUP BY product_id;
逻辑说明:按product_id分组后,每个分组内匹配对应的规格取值,用MAX/MIN这类聚合函数把分散在多行的规格值合并到同一行即可。
各数据库专属简化方案
MySQL专属:用
IF函数简化语法SELECT product_id, MAX(IF(spec = 'speed', value, NULL)) AS speed, MAX(IF(spec = 'weight', value, NULL)) AS weight, MAX(IF(spec = 'power', value, NULL)) AS power, MAX(IF(spec = 'autonomy', value, NULL)) AS autonomy FROM 你的表名 GROUP BY product_id;PostgreSQL专属:用
crosstab交叉表函数实现-- 首次使用需要先加载扩展,仅需执行一次 CREATE EXTENSION IF NOT EXISTS tablefunc; -- 行转列查询 SELECT * FROM crosstab( 'SELECT product_id, spec, value FROM 你的表名 ORDER BY 1,2', $$VALUES ('speed'::text), ('weight'::text), ('power'::text), ('autonomy'::text)$$ ) AS t(product_id text, speed int, weight int, power int, autonomy int);SQL Server/Oracle专属:用
PIVOT关键字实现SELECT * FROM ( SELECT product_id, spec, value FROM 你的表名 ) AS src PIVOT ( MAX(value) FOR spec IN ([speed], [weight], [power], [autonomy]) ) AS pvt;
补充说明
如果你的spec规格字段取值不固定、会动态新增,没法提前枚举所有规格名,可以编写存储过程动态拼接SQL语句,自动拉取所有spec取值生成对应查询逻辑即可。
内容的提问来源于stack exchange,提问作者Pato
相关产品推荐
相关产品推荐

