To może być czystsze podejście, którego szukasz. Zasadniczo sprawdź, czy zmienna została jeszcze zainicjowana. Jeśli nie, ustaw pusty ciąg znaków i dołącz pierwsze miasto (bez przecinka). Jeśli tak, dodaj przecinek, a następnie dodaj miasto.
DECLARE @col nvarchar(MAX);
SELECT @col = COALESCE(@col + ',', '') + city
FROM dbo.tbl WHERE state = 'California';
Oczywiście działa to tylko w przypadku zapełniania zmiennej według stanu. Jeśli wyciągasz listę dla każdego stanu pojedynczo, istnieje lepsze rozwiązanie w jednym ujęciu:
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];
Wyniki:
state cities
---------- --------------------------------------
California San Francisco, Los Angeles, Sacramento
Florida Miami, Jacksonville
Aby zamówić według nazwy miasta w każdym stanie:
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];
W usłudze Azure SQL Database lub SQL Server 2017+ możesz użyć nowej STRING_AGG()
funkcji :
SELECT [state], cities = STRING_AGG(city, N', ')
FROM dbo.tbl
GROUP BY [state]
ORDER BY [state];
I uporządkowane według nazwy miasta:
SELECT [state], cities = STRING_AGG(city, N', ')
WITHIN GROUP (ORDER BY city)
FROM dbo.tbl
GROUP BY [state]
ORDER BY [state];
Aby dodać do powyższej odpowiedzi Aarona ...
Pamiętaj, że
ORDER BY
może dojść do złamania, włączając tylko ostatni element do zapytania. W moim przypadku nie grupowałem, więc nie jestem pewien, czy to robi różnicę. Używam SQL 2014. W moim przypadku mam coś takiego jak wartość1, wartość2, wartość3 ... ale mój wynik w zmiennej to tylko wartość3.Aaron skomentował:
Zostało to zgłoszone co najmniej cztery razy w Connect:
Przykładowa odpowiedź Microsoft:
Odpowiedź odwołuje się również do KB 287515:
PRB: Plan wykonania i wyniki zagregowanych zapytań konkatenacyjnych zależą od lokalizacji wyrażenia
Rozwiązaniem jest użycie
FOR XML PATH
(drugie podejście w odpowiedzi Aarona), jeśli kolejność konkatenacji jest ważna i, oczywiście, jeśli chcesz mieć pewność, że uwzględnisz wszystkie wartości. Zobacz także:nvarchar concatenation / index / nvarchar (max) niewytłumaczalne zachowanie w przypadku przepełnienia stosu
źródło