You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.08 13:18:03