SQL-запрос для объединения значений из нескольких записей - PullRequest
2 голосов
/ 08 августа 2010

У меня есть таблица Сотрудники с сотрудниками (скажем, важными полями являются ID int, Имя varchar (50)) и таблица Области с областями продаж (ID int, EmployeeID int, USState char (2)).

Примеры значений:

Employees
ID     Name
1      Shoeman
2      Smith
3      Johnson

Areas
ID     EmployeeID     USState
1      1              NY
2      1              FL
3      1              AR
4      2              DC
5      2              AR
6      3              TX

Может кто-нибудь дать мне подсказку при создании запроса SQL для получения выходного набора записей следующим образом:

EmployeeID     USState
1              NY FL AR
2              DC AR
3              TX

Целевая платформа: SQL Server 2005.

Ответы [ 2 ]

2 голосов
/ 08 августа 2010

В MySQL эта операция называется GROUP_CONCAT , но SQL Server ее не поддерживает.

В SQL Server вы можете симулировать те же функции, используя FOR XML PATH hack.

SELECT extern.EmployeeID, states AS USState
FROM Areas AS extern
CROSS APPLY (
    SELECT USState + ' '
    FROM Areas AS intern
    WHERE extern.EmployeeID = intern.EmployeeID
    FOR XML PATH('')
) T1 (states)
GROUP BY extern.EmployeeID, states
ORDER BY extern.EmployeeID

Альтернативой является использование рекурсивного CTE . Это менее удачное решение, но оно более сложное:

WITH qs(EmployeeID, USState, rn, cnt) AS
(
    SELECT
        EmployeeID,
        USState,
        ROW_NUMBER() OVER (PARTITION BY EmployeeID ORDER BY USState),
        COUNT(*) OVER (PARTITION BY EmployeeID)
    FROM    Areas
),
t (EmployeeID, prodname, gc, rn, cnt) AS
(
    SELECT EmployeeID, USState, CAST(USState AS NVARCHAR(MAX)), rn, cnt
    FROM qs
    WHERE rn = 1
    UNION ALL
    SELECT
        qs.EmployeeID, qs.USState,
        CAST(t.gc + ' ' + qs.USState AS NVARCHAR(MAX)),
        qs.rn, qs.cnt
    FROM t
    JOIN qs ON qs.EmployeeID = t.EmployeeID
           AND qs.rn = t.rn + 1
)
SELECT EmployeeID, gc AS USState
FROM   t
WHERE  rn = cnt
ORDER BY EmployeeID
OPTION (MAXRECURSION 0)

Оба метода дают желаемый результат:

EmployeeID     USState
1              NY FL AR 
2              DC AR 
3              TX 
1 голос
/ 20 мая 2011

Это мой лучший формат для использования UDF (кажется, намного быстрее и для большой БД)

CREATEFUNCTION dbo.StateList(@ID int) RETURNS varchar(max)

AS

DECLARE @out varchar(max);

SET @out=''; -- comment this out to reutrn NULL if nothing found

SELECT @out=@out+USState+' ' -- operates like a loop assigning the values in sequence to the out variable.

FROM AREAS
WHERE EmployeeID=@ID
ORDER BY USState

RETURN @out

Пример запроса ...

SELECT Name, dbo.StateList(EmployeeID)
FROM Employees
Order BY Name

Таким образом, вы создаете один UDF для каждого списка, который хотите взорвать таким образом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...