Получение данных из соединительной таблицы в виде списка значений для уникальных записей - PullRequest
0 голосов
/ 09 июня 2018

У меня есть две таблицы, связанные с отношением «многие ко многим» соединительной таблицей:

    CREATE TABLE [dbo].[User](
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [name] [nvarchar](50) NOT NULL,
    [surname] [nvarchar](50) NOT NULL,
)

    CREATE TABLE [dbo].[Room](
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [number] [nvarchar](50) NOT NULL
)

CREATE TABLE [dbo].[Permission](
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [user_id] [int] NOT NULL,
    [room_id] [int] NOT NULL
)

Я хочу создать запрос, который даст мне имя результата и имя пользователя из таблицы пользователя и списка комнат.у данного пользователя есть разрешение.Например:

name surname rooms
Jon  Doe     [134,143,132]

Мне удалось получить несколько результатов для Джона Доу по одному для каждой комнаты, но я не могу свернуть это, чтобы получить запись для каждого пользователя.

1 Ответ

0 голосов
/ 09 июня 2018

В SQL Server до 2017 года это можно сделать с помощью коррелированного подзапроса FOR XML.

SELECT [User].[name],
       [User].[surname],
       stuff((SELECT ',' + [Room].[number] [text()]
                     FROM [dbo].[Room]
                          INNER JOIN [dbo].[Permission]
                                     ON [Permission].[room_id] = [Room].[ID]
                          WHERE [Permission].[user_id] = [User].[ID]
              FOR XML PATH('')), 1, 1, NULL) [rooms]
       FROM [dbo].[User];

С 2017 года существует функция агрегации string_agg(), с которой можно объединять строки группы.

SELECT [User].[name],
       [User].[surname],
       string_agg([Room].[number], ',') [rooms]
       FROM [dbo].[User]
            INNER JOIN [dbo].[Permission]
                       ON [Permission].[user_id] = [User].[ID]
            INNER JOIN [dbo].[Room]
                       ON [Room].[ID] = [Permission].[room_id]
       GROUP BY [User].[ID],
                [User].[name],
                [User].[surname];

(Примечание: я добавил [User].[ID] к GROUP BY, так как может быть более одного пользователя с одинаковым именем.)

...