Мне нужен запрос, который помещает в один столбец все совпадающие значения из другой таблицы.
У меня есть три таблицы, которые отслеживают расписания людей. Таблица пользователя, таблица сеансов и таблица внешних ссылок расписаний.
Person Table
---------------------
PersonID FirstName
--------- ---------
167196 Mark
SessionLive Table
-------------------------
SessionCode SessionAtLocationID
----------- -------------------
T4182 8105
T4183 8106
T4190 8113
T4179 8102
XPersonSchedule Table of the Persons schedule
-------------------------------------------------
PersonID SessionAtLocationID
----------- -------------------
167196 8105
167196 8106
167196 8113
167196 8102
Этот выбор:
select Person.RecordNumber as PersonID, Person.FirstName
, SessionLive.SessionCode
from Person
join XPersonSchedule on XPersonSchedule.PersonID = RecordNumber
join SessionLive on
SessionLive.SessionAtLocationID = XPersonSchedule.SessionAtLocationId
where recordnumber = 167196
Дает мне это:
PersonID FirstName SessionCode
----------- ----------- ----------
167196 Mark T4182
167196 Mark T4183
167196 Mark T4190
167196 Mark T4179
Мне нужен выбор, который дает мне это вместо этого. Одна строка для каждого человека с их сеансами в одном столбце, разделенном cr/lf.
PersonID FirstName SessionCode
----------- ----------- -----------
167196 Mark T4182<crlf>T4183<crlf>T4190<crlf>T4179
Пожалуйста! Благодарю вас!
Спасибо, я забыл упомянуть, что это для MSSQL 2014. string-agg() был добавлен в 2017 году.
Подождите, PersonID
в таблице Person
на самом деле называется RecordNumber
? Это кажется... странным.
Это действительно уродливое решение в старых версиях жизнеобеспечения SQL Server:
SELECT PersonID = p.RecordNumber, p.FirstName,
SessionCodes = STUFF((
SELECT CONCAT(char(13),char(10),sl.SessionCode)
FROM dbo.SessionLive AS sl
INNER JOIN dbo.XPersonSchedule AS xps
ON sl.SessionAtLocationID = xps.SessionAtLocationID
WHERE xps.PersonID = p.RecordNumber
FOR XML PATH(''), TYPE
).value(N'./text()[1]', N'varchar(max)'), 1, 2, '')
FROM dbo.Person AS p
GROUP BY p.RecordNumber, p.FirstName;
Выход:
PersonID | Имя | Коды сеансов |
---|---|---|
167196 | Отметка | T4182 T4183 T4190 T4179 |
В новых версиях это немного проще (справочную информацию см. в Агрегация строк в течение многих лет в SQL Server):
SELECT PersonID = p.RecordNumber, p.FirstName,
SessionCodes = STRING_AGG(sl.SessionCode, char(13)+char(10))
FROM dbo.SessionLive AS sl
INNER JOIN dbo.XPersonSchedule AS xps
ON sl.SessionAtLocationID = xps.SessionAtLocationID
INNER JOIN dbo.Person AS p
ON xps.PersonID = p.RecordNumber
GROUP BY p.RecordNumber, p.FirstName;
Я возьму некрасивый!. Никто кроме меня не видит! Он работает так, как мне нужно. Собираюсь обновить mssql, как только закончу некоторые неотложные сроки. СПАСИБО! Не спрашивайте о RecordNunber, скажем, 22 года назад я только учился... Он никогда не менялся, а теперь изменить его было бы ОЧЕНЬ БОЛЬШИМ делом!
string_agg()
— функция, которую нужно использовать.