SQL Server Concaténer GROUP BY

J'ai une requête qui ressemble à ceci

SELECT J.JobID,T.Title FROM JobsTagMap J Left Join Tags T ON J.TagID=T.TagID 

Cela renvoie l'set de données suivant (simplifié, JobID est en fait un UniqueIdentifier)

 JobID Title 1 Tag1 1 Tag2 2 Tag2 2 Tag5 2 Tag9 

Maintenant, je voudrais regrouper cela par la colonne JobID et concaténer le titre, de sorte que les résultats sont les suivants

 JobID Title 1 Tag1,Tag2 2 Tag2,Tag5,Tag9 

Comment ferais-je cela?

Si vous utilisez SQL Server 2005+. Alors vous pouvez faire comme ceci:

 SELECT JobsTagMap.JobID, STUFF ( ( SELECT ',' +Title FROM Tags WHERE Tags.TagID=JobsTagMap.TagID FOR XML PATH('') ) ,1,1,'') AS Title FROM JobsTagMap 

MODIFIER

Parce que vous ne nous avez pas montré la structure de la table et datatables dans les différentes tables. C'était un peu difficile à savoir. Donc, je suppose que votre structure de table ressemble à ceci:

 CREATE TABLE JobsTagMap ( JobID INT, TagID INT ) CREATE TABLE Tags ( TagID INT, Title VARCHAR(100) ) 

Avec ces données:

 INSERT INTO JobsTagMap VALUES(1,1),(1,2),(2,2),(2,4),(2,5) INSERT INTO Tags VALUES(1,'Tag1'),(2,'Tag2'),(3,'Tag2'),(4,'Tag5'),(5,'Tag9') 

Si vous obtenez datatables que vous affichez, le JobID ne peut pas être unique. Vous pourriez avoir la table Job un endroit où elle est unique. Si vous voulez juste utiliser cette table que vous montrez alors vous devez faire quelque chose comme ceci:

 ;WITH CTE AS ( SELECT ROW_NUMBER() OVER(PARTITION BY JobID ORDER BY JobID) AS RowNbr, JobsTagMap.* FROM JobsTagMap ) SELECT *, STUFF ( ( SELECT ',' +Title FROM Tags JOIN JobsTagMap ON Tags.TagID=JobsTagMap.TagID WHERE JobsTagMap.JobID=CTE.JobID FOR XML PATH('') ) ,1,1,'') AS Title FROM CTE WHERE CTE.RowNbr=1 

Cela vous obtiendra ce résultat:

 1 1 1 Tag1,Tag2 1 2 2 Tag2,Tag5,Tag9 

Donc, dans le futur montre toujours quelle structure de table et les données . Cela vous donnera de meilleures réponses

J'utilise une fonction scalaire pour exactement cela. Il va y avoir un puriste qui ne devrait jamais utiliser une opération basée sur les lignes, mais bon, cela fonctionne et si vous ne returnnez que quelques lignes, le time de réponse est correct.

 CREATE FUNCTION [dbo].[JoinMVText] ( @sID int, @fieldID tinyint ) RETURNS VARCHAR(MAX) AS BEGIN DECLARE @MVtextList varchar(max) SELECT @MVtextList = COALESCE(@MVtextList + '; ', '') + docMVtext.value FROM docMVtext with (nolock) WHERE docMVtext.sID = @sID and fieldID = @fieldID RETURN @MVtextList END