2012-05-05 4 views
4

У меня есть запрос, который выглядит как этотSQL Server Concatenate GROUP BY

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

Это возвращает следующий набор данных (упрощенный, JobID фактически UniqueIdentifier) ​​

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

Теперь я хотел бы чтобы сгруппировать их по столбцу JobID и объединить Заголовок, поэтому результаты следующие:

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

Как мне это сделать?

+2

см http://stackoverflow.com/questions/273238/how-to-use-group-by-to-concatenate-strings-in-sql-server –

+0

У меня был один из ответов, но ссылки выше отлично. Ответ от Arion использует тот же подход. – Paparazzi

ответ

10

Если вы используете SQL Server 2005+. Затем вы можете сделать так:

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

EDIT

Потому что ты не показал нам структуру таблицы и данные в разных таблицах. Это было трудно понять. Таким образом, я предполагаю, что ваша структура таблицы выглядит следующим образом:

CREATE TABLE JobsTagMap 
(
    JobID INT, 
    TagID INT 
) 

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

С помощью этих данных:

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') 

Если вы получаете, что данные, которые вы показываете JobID не может быть уникальным. У вас может быть таблица Job где-то там, где она уникальна. Если вы хотите использовать эти таблицы, которые вы выводите, то вам нужно сделать что-то вроде этого:

;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 

Это поможет вам этот результат:

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

Таким образом, в будущем всегда показывают, что таблица структура и это данные. Это даст вам лучшие ответы

+0

Это фактически вернуло те же данные, что и мой первый запрос ... –

+0

Я немного поработал с этим и добавил группу, наконец, «GROUP BY JobsTagMap.JobID», но затем я получаю эту ошибку «Column» JobTagMap.TagID 'недопустим в списке выбора, потому что он не содержится ни в агрегатной функции, ни в предложении GROUP BY. " –

+0

Обновлен ответ – Arion

1

Я использую для этого именно скалярную функцию. Там будет какой-то пурист, который не должен использовать операцию на основе строк, но это работает, и если вы возвращаете только несколько строк, время отклика в порядке.

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