J'essaie d'atteindre les objectifs suivants:
California | Los Angeles, San Francisco, Sacramento
Florida | Jacksonville, Miami
Malheureusement, je reçois ", Los Angeles, San Francisco, Sacramento, Jacksonville, Miami"
Je peux obtenir les résultats souhaités en utilisant la fonction STUFF, mais je me demandais s'il y avait une façon plus propre de le faire en utilisant COALESCE?
STATE | CITY
California | San Francisco
California | Los Angeles
California | Sacramento
Florida | Miami
Florida | Jacksonville
DECLARE @col NVARCHAR(MAX);
SELECT @col= COALESCE(@col, '') + ',' + city
FROM tbl where city = 'California';
SELECT @col;
Merci
Cela pourrait être l'approche plus propre que vous recherchez. Fondamentalement, vérifiez si la variable a encore été initialisée. Si ce n'est pas le cas, définissez-le sur la chaîne vide et ajoutez la première ville (pas de virgule principale). Si c'est le cas, ajoutez une virgule, puis ajoutez la ville.
DECLARE @col nvarchar(MAX);
SELECT @col = COALESCE(@col + ',', '') + city
FROM dbo.tbl WHERE state = 'California';
Bien sûr, cela ne fonctionne que pour remplir une variable par état. Si vous tirez la liste pour chaque état un par un, il existe une meilleure solution en une seule fois:
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];
Résultats:
state cities
---------- --------------------------------------
California San Francisco, Los Angeles, Sacramento
Florida Miami, Jacksonville
Pour commander par nom de ville dans chaque état:
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];
Dans Azure SQL Database ou SQL Server 2017+, vous pouvez utiliser la nouvelle fonction STRING_AGG()
:
SELECT [state], cities = STRING_AGG(city, N', ')
FROM dbo.tbl
GROUP BY [state]
ORDER BY [state];
Et classés par nom de ville:
SELECT [state], cities = STRING_AGG(city, N', ')
WITHIN GROUP (ORDER BY city)
FROM dbo.tbl
GROUP BY [state]
ORDER BY [state];
Juste pour ajouter à réponse d'Aaron ci-dessus ...
Sachez qu'un ORDER BY
peut ne fonctionner qu'en incluant le dernier élément de votre requête. Dans mon cas, je ne faisais pas de regroupement, donc je ne sais pas si cela fait une différence. J'utilise SQL 2014. Dans mon cas, j'ai quelque chose comme value1, value2, value3 ... mais mon résultat dans la variable n'était que value3.
Aaron a commenté:
Cela a été signalé au moins quatre fois sur Connect:
Exemple de réponse de Microsoft:
Le comportement que vous voyez est de par leur conception. L'utilisation d'opérations d'affectation (concaténation dans cet exemple) dans les requêtes avec la clause ORDER BY a un comportement indéfini.
La réponse fait également référence à KB 287515:
La solution consiste à utiliser FOR XML PATH
(la deuxième approche dans la réponse d'Aaron) si l'ordre de concaténation est important et, bien sûr, si vous voulez être sûr d'inclure toutes les valeurs. Regarde aussi:
concaténation nvarchar/index/nvarchar (max) comportement inexplicable on Stack Overflow