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

SQL多列值合并为单列求助:如何将关联值合并到同一行

嗨,这个问题我帮你搞定!你当前用UNION的写法会把每个关联的Location拆成单独行,而我们需要把同一个HostName对应的多个Name合并成一行空格分隔的字符串。下面分不同数据库给你对应的解决方案:

方法一:通用聚合思路(适合所有支持字符串聚合的数据库)

这种思路先把所有非空的LID列统一转成一列,再关联Location表,最后按HostName分组聚合字符串。

MySQL/MariaDB 版本

SELECT 
    i.HostName,
    GROUP_CONCAT(l.Name SEPARATOR ' ') AS Name
FROM (
    -- 提取所有非空的LID与HostName的关联
    SELECT HostName, LID1 AS LID FROM inventory WHERE LID1 IS NOT NULL
    UNION ALL
    SELECT HostName, LID2 AS LID FROM inventory WHERE LID2 IS NOT NULL
    UNION ALL
    SELECT HostName, LID3 AS LID FROM inventory WHERE LID3 IS NOT NULL
) AS i
INNER JOIN location l ON i.LID = l.ID
GROUP BY i.HostName;

这里用UNION ALL代替UNION会更高效,因为不需要额外去重操作;GROUP_CONCAT负责把分组后的Name用空格连接起来。

SQL Server(2017+)/ PostgreSQL 版本

SELECT 
    i.HostName,
    STRING_AGG(l.Name, ' ') AS Name
FROM (
    SELECT HostName, LID1 AS LID FROM inventory WHERE LID1 IS NOT NULL
    UNION ALL
    SELECT HostName, LID2 AS LID FROM inventory WHERE LID2 IS NOT NULL
    UNION ALL
    SELECT HostName, LID3 AS LID FROM inventory WHERE LID3 IS NOT NULL
) AS i
INNER JOIN location l ON i.LID = l.ID
GROUP BY i.HostName;

逻辑和MySQL一致,只是用STRING_AGG作为字符串聚合函数,这两个数据库的语法完全相同。

Oracle(11gR2+)版本

SELECT 
    i.HostName,
    LISTAGG(l.Name, ' ') WITHIN GROUP (ORDER BY l.Name) AS Name
FROM (
    SELECT HostName, LID1 AS LID FROM inventory WHERE LID1 IS NOT NULL
    UNION ALL
    SELECT HostName, LID2 AS LID FROM inventory WHERE LID2 IS NOT NULL
    UNION ALL
    SELECT HostName, LID3 AS LID FROM inventory WHERE LID3 IS NOT NULL
) AS i
INNER JOIN location l ON i.LID = l.ID
GROUP BY i.HostName;

Oracle的LISTAGG需要指定WITHIN GROUP子句,这里按Name排序能保证结果和你预期的顺序一致(比如Peter的AAA BBB CCC)。

方法二:直接拼接(适合固定3个LID列的场景)

如果你的Inventory表只会有LID1、LID2、LID3这三个列,也可以直接通过子查询获取每个LID对应的Name,再拼接起来:

MySQL/MariaDB 版本

SELECT 
    HostName,
    CONCAT_WS(' ', 
        CASE WHEN LID1 IS NOT NULL THEN (SELECT Name FROM location WHERE ID = LID1) END,
        CASE WHEN LID2 IS NOT NULL THEN (SELECT Name FROM location WHERE ID = LID2) END,
        CASE WHEN LID3 IS NOT NULL THEN (SELECT Name FROM location WHERE ID = LID3) END
    ) AS Name
FROM inventory;

CONCAT_WS会自动忽略空值,所以如果某个LID为空,不会在结果里产生多余的空格。

两种方法各有优势:方法一扩展性更强,以后如果增加LID4、LID5,只需在子查询里加一行;方法二写法更直接,适合列数固定的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 13:32:40