SQL行转列(透视表)问题:如何修正查询以合并同一实体的字段值并得到预期结果?
SQL行转列(透视表)问题:如何修正查询以合并同一实体的字段值并得到预期结果?
看起来你是想把「键值对」形式存储的values表数据,转成「宽表」格式——每个实体一行、每个字段一列。你的思路方向是对的,但问题出在分组逻辑和聚合处理上,我来帮你梳理一下:
先明确你的表结构(从截图推断)
fields表:定义了所有字段的元数据,比如id对应字段ID,name是字段名(像Finished、Faculty这些)values表:存储每个实体的具体字段值,entity_id用来区分不同的实体(比如Math和Biology是两个不同的实体),field_id关联到fields表,value是字段的实际值
你的原查询问题在哪里?
你现在的GROUP BY flds.id, vals.value会把每个字段的每个值单独分组,导致每个字段值都生成一行,而不是把同一个实体的所有字段合并到一行。而且你完全没用到entity_id——这个字段才是把不同字段值绑定到同一个实体的核心!
修正后的查询
你需要用聚合函数(比如MAX())提取每个字段对应实体的值,并且按entity_id分组,把同一个实体的所有字段行合并成一行:
SELECT MAX(CASE WHEN flds.name = 'Finished' THEN vals.value END) AS Finished, MAX(CASE WHEN flds.name = 'Faculty' THEN vals.value END) AS Faculty, MAX(CASE WHEN flds.name = 'Characteristic' THEN vals.value END) AS Characteristic, MAX(CASE WHEN flds.name = 'Photo' THEN vals.value END) AS Photo FROM `values` vals LEFT JOIN `fields` flds ON vals.field_id = flds.id GROUP BY vals.entity_id; -- 按实体ID分组,确保同一个实体的字段值都合并到一行
为什么这样能解决问题?
MAX()聚合函数:对于每个实体来说,每个字段只会有一个对应的值,MAX()会留下这个有效值,自动忽略其他字段对应的NULL值- 按
entity_id分组:这是关键!它告诉SQL要把同一个实体的所有字段行合并成一行,而不是按字段或者值拆分 - 去掉了原查询中错误的
flds.id和vals.value分组条件,避免了把同一实体的不同字段拆分成多行
如果你的values表中entity_id对应的实体还有其他信息(比如实体名称),可以额外关联对应的表来补充,但仅按现有表结构,上面的查询就能得到你想要的结果啦。
备注:内容来源于stack exchange,提问作者Yang
相关产品推荐
相关产品推荐

