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

如何通过SQL关联多SELECT语句并实现行转列(空值留空)

解决行转列需求:将键值对表转为宽表

你的需求是把Persons表的键值对结构转成宽表(每个姓名一行,Info的不同取值作为列),缺失对应Info的单元格留空。下面提供两种可行方案,同时解释如何关联多个子查询:


方法1:条件聚合(推荐,通用所有SQL数据库)

这种方法仅需扫描一次表,代码简洁且性能更优,通过CASE语句配合聚合函数提取对应列的值,缺失值自动显示为NULL(空单元格)。

SELECT
    Name,
    MAX(CASE WHEN Info = 'Height' THEN Value END) AS Height,
    MAX(CASE WHEN Info = 'Weight' THEN Value END) AS Weight,
    MAX(CASE WHEN Info = 'Hair' THEN Value END) AS Hair
FROM Persons
GROUP BY Name
ORDER BY Name;

说明

因为每个Name对应每个Info只有一条记录,用MAX(或MIN/SUM均可,这里MAX最直观)就能精准提取对应值;没有匹配Info时,CASE返回NULL,聚合后仍为NULL,即显示空单元格。


方法2:通过LEFT JOIN关联三个子查询

如果需要用子查询关联的方式实现,必须用LEFT JOIN而非INNER JOIN——INNER JOIN会过滤掉缺失任意Info的姓名,而LEFT JOIN能保留所有姓名,缺失值显示为NULL。

更清晰的写法是先获取所有唯一姓名作为基础表,再分别关联各Info的子查询:

SELECT
    n.Name,
    w.Weight,
    h.Height,
    hr.Hair
FROM
    (SELECT DISTINCT Name FROM Persons) AS n
LEFT JOIN
    (SELECT Name, Value AS Weight FROM Persons WHERE Info = 'Weight') AS w ON n.Name = w.Name
LEFT JOIN
    (SELECT Name, Value AS Height FROM Persons WHERE Info = 'Height') AS h ON n.Name = h.Name
LEFT JOIN
    (SELECT Name, Value AS Hair FROM Persons WHERE Info = 'Hair') AS hr ON n.Name = hr.Name
ORDER BY n.Name;

说明

  1. 先通过SELECT DISTINCT Name获取所有唯一姓名,确保不会遗漏任何行;
  2. 对每个Info对应的子查询做LEFT JOIN,即使某个姓名没有该Info的值,对应列也会显示空单元格;
  3. 若直接关联三个子查询,需用COALESCE处理姓名字段的NULL情况,但基础表+LEFT JOIN的写法更易维护。

内容的提问来源于stack exchange,提问作者Zqm

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 20:11:27