2010-06-25 5 views
1

J'ai la requête suivante qui retourne le salaire de tous les employés. Cela fonctionne parfaitement, mais j'ai besoin de collecter des données supplémentaires que je regrouperai dans une cellule (voir le jeu de résultats 2).Comment concaténer plusieurs lignes?

Comment agréger des données dans une liste séparée par des virgules? Un peu comme Sum, mais j'ai besoin d'une corde en retour.

SELECT Employee.Id, SUM(Pay) as Salary 
FROM Employee 
INNER JOIN PayCheck ON PayCheck.EmployeeId = Employee.Id 
GROUP BY Employee.Id 

Jeu de résultats 1

Employee.Id    Salary 
----------------------------------- 
      1     150 
      2     250 
      3     350 

J'ai besoin:

Résultat Set 2

Employee.Id    Salary     Data 
---------------------------------------------------- 
      1     150  One, Two, Three 
      2     250  Four, Five, Six 
      3     350  Seven 
+0

duplication possible de [Comment créer une liste séparée par des virgules à l'aide d'une requête SQL?] (http://stackoverflow.com/questions/1817985/how-do-i-create -a-comma-separated-list-using-a-sql-query) et de http://stackoverflow.com/questions/3087684/sql-query-to-return-values-of-a-particular-column-concactenated -with-virgule/3087799 # 3087799 @Martin ce dernier a un meilleur examen Il est également possible d'utiliser un agrégat CLR personnalisé. –

+1

Peut-être que j'ai manqué quelque chose ici, mais d'où obtenez-vous les données supplémentaires? – VoodooChild

+0

SqlServer 2017 a maintenant STRING_AGG qui agrège plusieurs chaînes en une en utilisant un séparateur donné. (Pas autorisé à poster une réponse en double à une question en double.) – John

Répondre

3

Pour SQL Server 2005+, utilisez la fonction STUFF et FOR XML PATH:

WITH summary_cte AS (
    SELECT Employee.Id, SUM(Pay) as Salary 
    FROM Employee 
    JOIN PayCheck ON PayCheck.EmployeeId = Employee.Id 
GROUP BY Employee.Id) 
SELECT sc.id, 
     sc.salary, 
     STUFF((SELECT ','+ yt.data 
       FROM your_table yt 
       WHERE yt.id = sc.id 
      GROUP BY yt.data 
      FOR XML PATH(''), TYPE).value('.','VARCHAR(max)'), 1, 1, '') 
    FROM summary_cte sc 

Mais vous manquez de détails sur l'endroit où les données que vous souhaitez transformer en une chaîne délimitée par des virgules, et comment il se rapporte à un enregistrement d'employé ...

+0

cela ne gère pas correctement les caractères spéciaux XML comme '>' et '&'. Donc, si your_table.data contenait 'one & two', vous obtiendriez' un & two' dans le jeu de résultats. Il y a une manière astucieuse de manipuler ceci, voir: http://stackoverflow.com/questions/5031204/does-t-sql-have-an-aggregate-function-to-concatenate-strings/5031297#5031297 –

+0

@KM: Cool - mis à jour, upvote à vous! –

0

Je n'ai pas mon code devant moi, ou je voudrais vous montrer un exemple rapide, mais je wo Nous devrions écrire un agrégat CLR pour cela. C'est très simple. Il y a une méthode créée automatiquement à utiliser, et ils sont juste pour collectionner (ajouter à un objet List <> ou quelque chose), Fusionner (fusionner plusieurs listes créées dans plusieurs threads), et une sortie (prendre la liste et la transformer en une chaîne - String.Join (",", list.ToArray())). La seule chose à savoir est qu'il y a une limite de longueur de 8000 caractères.

Questions connexes