Это может быть более чистый подход, который вы ищете. В основном, проверьте, была ли переменная еще инициализирована. Если это не так, установите пустую строку и добавьте первый город (без запятой). Если это так, добавьте запятую, а затем добавьте город.
DECLARE @col nvarchar(MAX);
SELECT @col = COALESCE(@col + ',', '') + city
FROM dbo.tbl WHERE state = 'California';
Конечно, это работает только для заполнения переменной в каждом штате. Если вы вытягиваете список для каждого состояния по одному, есть лучшее решение за один раз:
SELECT [state], cities = STUFF((
SELECT N', ' + city FROM dbo.tbl
WHERE [state] = x.[state]
FOR XML PATH(''), TYPE).value(N'.[1]', N'nvarchar(max)'), 1, 2, N'')
FROM dbo.tbl AS x
GROUP BY [state]
ORDER BY [state];
Полученные результаты:
state cities
---------- --------------------------------------
California San Francisco, Los Angeles, Sacramento
Florida Miami, Jacksonville
Для заказа по названию города в каждом штате:
SELECT [state], cities = STUFF((
SELECT N', ' + city FROM dbo.tbl
WHERE [state] = x.[state]
ORDER BY city
FOR XML PATH(''), TYPE).value(N'.[1]', N'nvarchar(max)'), 1, 2, N'')
FROM dbo.tbl AS x
GROUP BY [state]
ORDER BY [state];
В базе данных SQL Azure или SQL Server 2017+ вы можете использовать новую STRING_AGG()
функцию :
SELECT [state], cities = STRING_AGG(city, N', ')
FROM dbo.tbl
GROUP BY [state]
ORDER BY [state];
И упорядочено по названию города:
SELECT [state], cities = STRING_AGG(city, N', ')
WITHIN GROUP (ORDER BY city)
FROM dbo.tbl
GROUP BY [state]
ORDER BY [state];
Просто чтобы добавить ответ Аарона выше ...
Имейте в
ORDER BY
виду, что может сломаться, только включив последний элемент в ваш запрос. В моем случае я не группировался, поэтому не уверен, что это имеет значение. Я использую SQL 2014. В моем случае у меня есть что-то вроде value1, value2, value3 ... но мой результат в переменной был только value3.Аарон прокомментировал, чтобы сказать:
Об этом сообщалось как минимум четыре раза в Connect:
Пример ответа от Microsoft:
Ответ также ссылается на KB 287515:
PRB: план выполнения и результаты агрегированных конкатенационных запросов зависят от местоположения выражения
Решение состоит в том, чтобы использовать
FOR XML PATH
(второй подход в ответе Аарона), если важен порядок конкатенации, и, конечно, если вы хотите быть уверены, что включили все значения. Также см:Конкатенация nvarchar / index / nvarchar (max) необъяснимое поведение при переполнении стека
источник