【问题标题】:How do you merge multiple rows into a single row in Microsoft SQL Server Management Studio, separate by comma如何在 Microsoft SQL Server Management Studio 中将多行合并为一行,用逗号分隔
【发布时间】:2026-01-29 01:50:01
【问题描述】:

我正在尝试根据匹配的 user_id 将以下 ID 连接到一行中。

当前代码

SELECT
A.USER_ID,
B.POINT_ID

FROM DATABASE1 AS A
LEFT JOIN DATABASE2 as b on a.SSCL_ID = b.SEC_ID

WHERE
RECORD_STATUS in ('2','5')
and USER_STATUS = '1'

我尝试了以下代码:

SELECT c.USER_ID,
    STUFF((SELECT DISTINCT ',' + cast(POINT_ID as varchar(10))
            FROM DATABASE1 A
            LEFT JOIN DATABASE2 as b on a.SSCL_ID = b.SEC_ID
            FOR XML PATH ('')), 1, 1, '') 
    from DATABASE1 c
      WHERE
       RECORD_STATUS in ('2','5')
       and USER_STATUS = '1'
    group by c.USER_ID

【问题讨论】:

  • 您在子查询中缺少 WHERE 的隐式 JOIN
  • 不确定我是否理解您的评论。我在 a.SSCL_ID = b.SEC_ID 上有 LEFT JOIN DATABASE2 作为 b。有什么需要补充的吗?
  • 那么cab有什么关系呢?这是您查询中的交叉连接。 c 与子查询中的每一行 行相关(由来自ab 的数据组成)。
  • 在提出问题时,您需要提供一个可重现的最小示例。请参考以下链接:*.com/help/minimal-reproducible-example 请提供以下内容: (1) DDL 和样本数据填充,即 CREATE table(s) 加上 INSERT T-SQL 语句。 (2) 你需要做什么,即逻辑和你的代码尝试在 T-SQL 中实现它。 (3) 期望的输出,基于上面#1 中的样本数据。 (4) 你的 SQL Server 版本 (SELECT @@version;)

标签: sql sql-server ssms


【解决方案1】:

请尝试以下解决方案。

SQL

-- DDL and sample data population, start
DECLARE @tbl TABLE (ID INT IDENTITY PRIMARY KEY, [USER_ID] VARCHAR(10), POINT_ID INT);
INSERT INTO @tbl ([USER_ID], POINT_ID) VALUES
('T0070',1 ),
('T0070',2 ),
('T0070',3 ),
('T1234',10),
('T1234',11),
('T1234',12),
('T1234',13),
('T1234',14);
-- DDL and sample data population, end

DECLARE @separator CHAR(1) = ',';

SELECT p.[USER_ID], 
   STUFF((SELECT @separator + CAST(POINT_ID AS VARCHAR(30)) AS [text()]
      FROM @tbl AS c
      WHERE c.[USER_ID] = p.[USER_ID] 
      ORDER BY c.POINT_ID
      FOR XML PATH(''), TYPE).value('text()[1]','NVARCHAR(MAX)'), 1, 1, NULL) AS POINT_ID_LIST
FROM @tbl AS p
GROUP BY p.USER_ID;

输出

+---------+----------------+
| USER_ID | POINT_ID_LIST  |
+---------+----------------+
| T0070   |          1,2,3 |
| T1234   | 10,11,12,13,14 |
+---------+----------------+

【讨论】:

  • @Charlieface,谢谢,考虑到了。 OP安静了很久。
【解决方案2】:

内部FOR XML PATH聚合必须是外部USER_ID的函数

with cte as(
    SELECT
      A.USER_ID,
      B.POINT_ID
    FROM DATABASE1 AS A
    LEFT JOIN DATABASE2 as b on a.SSCL_ID = b.SEC_ID
    WHERE
      RECORD_STATUS in ('2','5')
      and USER_STATUS = '1'
)
SELECT c1.USER_ID,
    STUFF((SELECT ',' + cast(POINT_ID as varchar(10))
            FROM cte c2
            WHERE c2.USER_ID = c1.USER_ID
            FOR XML PATH ('')), 1, 1, '')
FROM cte c1

【讨论】:

  • FOR XML PATH (''), TYPE).value('text()[1]','nvarchar(max)'), 1, 1, '') 防止 XML 实体化
【解决方案3】:

你能用string_agg()吗?

SELECT A.USER_ID, STRING_AGG(B.POINT_ID, ',')
FROM DATABASE1 A LEFT JOIN
     DATABASE2 b 
     ON a.SSCL_ID = b.SEC_ID
WHERE RECORD_STATUS in ('2', '5') AND
      USER_STATUS = '1'
GROUP BY A.USER_ID;

【讨论】:

  • 嗨,戈登。刚刚尝试过,它给了我错误“'STRING_AGG' 不是可识别的内置函数名称。”
  • @Meowzz 你需要 SQL Server 2017+
最近更新 更多