2010-08-08 2 views
2

У меня есть таблица Сотрудники с сотрудниками (например, важными полями являются ID int, Name varchar (50)) и таблица Области с областями продаж (ID int, EmployeeID int, USState символ (2)).SQL-запрос для объединения значений из нескольких записей

Значения выборок:

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 .

+0

См. Также: http://stackoverflow.com/questions/451415/simulating-group-concat-mysql-function-in-ms-sql-server-2005 –

ответ

2

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

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

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 

Альтернативой является использование recursive CTE. Это менее Hacky решение, но оно также является более сложным:

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 
+0

Ваш код «взлома» выполнил эту работу! Спасибо за вашу помощь –

+0

Мне нравится CTE, но до сих пор не время рекурсивно CTE. Спасибо за интересный пример! – Oleg

1

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

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 @[email protected]+USState+' ' -- operates like a loop assigning the values in sequence to the out variable. 

FROM AREAS 
WHERE [email protected] 
ORDER BY USState 

RETURN @out 

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

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

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

Смежные вопросы