106 votes

Résultats séparés par des virgules en SQL

J'ai le code suivant qui va créer une liste délimitée par des virgules pour mes résultats :

DECLARE @listStr VARCHAR(MAX)
SELECT @listStr = COALESCE(@listStr+', ' ,'') + INSTITUTIONNAME
FROM EDUCATION
WHERE STUDENTNUMBER= '111'
SELECT @listStr

Le problème est qu'il crée une seule ligne massive délimitée par des virgules. Je veux qu'il retourne une liste séparée par des virgules par ligne.

Donc si Simon a été membre de 2 institutions, alors je m'attends à :

"INSTITUTION1, INSTITUTION2"

Comme je n'ai pas fourni de clause WHERE, je m'attends à ce que mes résultats s'affichent comme ceci pour chaque ligne dans la base de données.

167voto

Nithesh Points 3247

Mise à jour (comme suggéré par @Aaron dans le commentaire)

STRING_AGG est la manière préférée de le faire dans les versions modernes de SQL Server (2017 ou ultérieure). Il prend également en charge un classement facile.

SELECT
    NUMÉROÉTUDIANT
    , STRING_AGG(NOMINSTITUTION, ', ') AS ListeStringAgg
    , STRING_AGG(NOMINSTITUTION, ', ') WITHIN GROUP (ORDER BY NOMINSTITUTION DESC) AS ListeStringAggDesc
FROM Éducation E
GROUP BY E.NUMÉROÉTUDIANT;

Réponse originale :

Utilisez FOR XML PATH('') - qui convertit les entrées en une chaîne séparée par des virgules et STUFF() - qui permet de supprimer la première virgule- comme suit. Ce qui vous donne le même résultat séparé par des virgules.

SELECT
    STUFF((SELECT ',' + NOMINSTITUTION
              FROM ÉDUCATION EE
              WHERE  EE.NUMÉROÉTUDIANT = E.NUMÉROÉTUDIANT
              ORDER BY tri
              FOR XML PATH(''), TYPE).value('text()[1]', 'nvarchar(max)')
        , 1, LEN(','), '') AS ListeXmlPath
FROM ÉDUCATION E
GROUP BY E.NUMÉROÉTUDIANT

Voici le FIDDLE montrant les résultats pour à la fois STRING_AGG et FOR XML PATH('').

99voto

Simon_Weaver Points 31141

Pour Sql Server 2017 et ultérieur, vous pouvez utiliser la fonction STRING_AGG

https://learn.microsoft.com/en-us/sql/t-sql/functions/string-agg-transact-sql

L'exemple suivant remplace les valeurs nulles par 'N/A' et renvoie les noms séparés par des virgules dans une seule cellule de résultat.

SELECT STRING_AGG ( ISNULL(FirstName,'N/A'), ',') AS csv 
FROM Person.Person;

Voici l'ensemble de résultats.

John,N/A,Mike,Peter,N/A,N/A,Alice,Bob

Un cas d'utilisation plus courant consiste à regrouper puis à agréger, tout comme vous le feriez avec SUM, COUNT ou AVG.

SELECT a.articleId, title, STRING_AGG (tag, ',') AS tags 
FROM dbo.Article AS a       
LEFT JOIN dbo.ArticleTag AS t 
    ON a.ArticleId = t.ArticleId 
GROUP BY a.articleId, title;

17voto

Xtian11 Points 93

Cela fonctionne dans SQL Server 2016

USE AdventureWorks
GO
DECLARE @listStr VARCHAR(MAX)
SELECT @listStr = COALESCE(@listStr+',' ,'') + Nom
FROM Production.Product
SELECT @listStr
GO

-2voto

ryguy7272 Points 2017

Je viens de voir une autre question très similaire à celle-ci!

Voici l'exemple de base de données canonique de NORTHWIND (orthographié légèrement différemment pour une raison quelconque).

SELECT *
FROM [NORTHWND].[dbo].[Products]

entrer la description de l'image ici

SELECT CategoryId,
           MAX( CASE seq WHEN 1 THEN ProductName ELSE '' END ) + ', ' +
           MAX( CASE seq WHEN 2 THEN ProductName ELSE '' END ) + ', ' +
           MAX( CASE seq WHEN 3 THEN ProductName ELSE '' END ) + ', ' +
           MAX( CASE seq WHEN 4 THEN ProductName ELSE '' END )
      FROM ( SELECT p1.CategoryId, p1.ProductName,
                    ( SELECT COUNT(*) 
                        FROM NORTHWND.dbo.Products p2
                        WHERE p2.CategoryId = p1.CategoryId
                        AND p2.ProductName <= p1.ProductName )
             FROM NORTHWND.dbo.Products p1 ) D ( CategoryId, ProductName, seq )
     GROUP BY CategoryId ;

entrer la description de l'image ici

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X