Строки SQL с предполагаемыми повторяющимися идентификаторами — как их объединить?

У меня есть несколько таблиц пользователей и отделов, которые объединены вместе, но с возможностью включения нескольких адресов электронной почты руководителя.

В идеале я бы хотел, чтобы они были отделены от основного набора данных; однако в представлении отчетов я хотел бы объединить их всех.

Как выглядят данные в настоящее время

ID Name
157 Bob
157 James
300 Phil
300 Keith
300 Paul

Как бы я хотел, чтобы это выглядело

ID Name
157 Bob, James
300 Phil, Keith, Paul

В качестве альтернативы в разных столбцах, в зависимости от того, что проще.

Текущий код аналогичен приведенному ниже.

Select 
TU.ID, 
TUbyDept.FirstName, 
TU.LastAccessData

FROM USERDATA UD
LEFT JOIN DepartmentData DD 
    ON UD.DepartmentID = DD.ID

LEFT JOIN UserData UDByDept ON DD.id = UDByDept.DepartmentID

Любая помощь будет оценена по достоинству, так как все, что я пробовал до сих пор, не слишком хорошо!

Использование SSMS 2016


person Jack Wheatley    schedule 13.01.2021    source источник


Ответы (2)


Если ваш SQL Server более ранний, чем SQL Server 2017, то что-то вроде этого должно сработать.

WITH userlist (ID,[Name])
AS (SELECT ID,[Name] FROM YourSourceTable)
SELECT ID,
STUFF((SELECT [Name] + ',' 
    FROM userlist
    WHERE ID=users.ID
    FOR XML PATH(''))
    ,1,2,'')
FROM userlist users
GROUP BY ID;

Я использовал Common Table Expression, потому что я не уверен, как выглядит ваш исходный не агрегированный/конкатенированный исходный код. Таким образом, просто замените SELECT ID,[Name] FROM YourSourceTable в моем коде вашим фактическим исходным кодом для вашей 1-й таблицы (как данные выглядят в настоящее время).

Вам будет гораздо проще работать с SQL Server 2017 и более поздними версиями, поскольку они поставляются с функцией STRING_AGG(). Подробнее об этом в MSDN.

person t4r4z0k    schedule 13.01.2021

Может быть, немного хакерским и, вероятно, достаточным только для небольших наборов данных:

declare @x as xml=(select id,[name] from userdata for xml raw);
with distinctusers as
(
  select id from userdata group by id
)
select 
  d.id,
  x.t.query('row[@id=sql:column("id")]').query('distinct-values(row/@name)')

  from distincusers d
  outer apply @x.nodes('.') as x(t)
person ub_coding    schedule 13.01.2021