【问题标题】:Merge multiple results to one Column将多个结果合并到一列
【发布时间】:2019-07-01 13:05:46
【问题描述】:

我想创建一个选择语句来将多个结果合并为一个 rot

我能够通过 PHP 实现我想要的,但我认为应该可以直接使用 Sql。

Notes
| ID | Name |
|----|------|
| 2  | Test |
| 3  | Test |

EditorAssignment
| UserID | NoteID |
|--------|--------|
| 1      | 2      |
| 2      | 2      |

UserList
| ID | username |
|----|----------|
| 1  | testuser |
| 2  | bUser    |
| 3  | cUser    |

我想得到以下结果:

| NoteID | User            |
|--------|-----------------|
| 2      | testuser, bUser |
| 3      | cUser           |

如何在 SQL2012 中创建类似的选择?

【问题讨论】:

  • 给我们你的代码,到目前为止你做了什么?

标签: sql-server database select aggregation


【解决方案1】:

在 SQL Server 2017 之前(有 STRING_AGG 聚合函数),您需要使用著名的 FOR XML PATH 相关子查询:

设置:

DECLARE @Notes TABLE (ID INT, Name VARCHAR(10))

INSERT INTO @Notes (ID, Name) 
VALUES (2, 'Test'), (3, 'Test')

DECLARE @EditorAssignment TABLE (UserID INT, NoteID INT)

INSERT INTO @EditorAssignment (UserID, NoteID)
VALUES (1, 2), (2, 2), 
    (3, 3) -- Added missing row here

DECLARE @UserList TABLE (ID INT, username VARCHAR(100))

INSERT INTO @UserList (ID, username)
VALUES (1, 'testuser'), (2, 'bUser'), (3, 'cUser')

查询:

SELECT
    NoteID = N.ID,
    [User] = STUFF(
        (
            SELECT
                ', ' + U.username
            FROM
                @EditorAssignment AS E
                INNER JOIN @UserList AS U ON E.UserID = U.ID
            WHERE
                N.ID = E.NoteID     -- Link the outmost Notes' note with the inner EditorAssignment (correlated subquery)
            FOR XML
                PATH ('')           -- FOR XML PATH('') makes the SELECT return a string value, not a result set
        ),
        1, 
        2, 
        '')
FROM
    @Notes AS N

结果:

NoteID  User
2       testuser, bUser
3       cUser

子查询为每个笔记的相关分配生成一个包含每个用户名的字符串。

STUFF 函数仅用于替换第一个', ',因为字符串是用前导逗号和空格构建的。这就是为什么 STUFF 的参数是 1(字符串的第一个位置)、2(要删除的位置数量、逗号和空格)和 ''(这些字符的替换)。

我猜您的示例中包含 3, 3 值的 EditorAssignment 表缺少一行。

【讨论】:

  • 对,但是当我使用这样的东西时,它最终会得到像“2; testuser,testuser”和“2; bUser, bUser”这样的结果
  • @MThiele 请包含完整示例和您正在使用的实际查询。我无法重现您所说的内容,也无法修复我看不到的内容。
  • 对不起,这是我的错。我在子选择中犯了一个错误。感谢四位您的时间!
  • @MThiele 很高兴为您提供帮助。
猜你喜欢
  • 1970-01-01
  • 2011-06-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-09-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多