2010-08-08 76 views
2

我有一张表雇员与员工(说重要的领域是ID int,名称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 – 2010-08-08 10:54:36

回答

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。这是一个不太哈克解决方案,但它也更复杂:

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

您的'hack'代码完成了这项工作!感谢您的帮助 – 2010-08-08 13:12:52

+0

我喜欢CTE,但到目前为止没有时间使用递归CTE。感谢这个有趣的例子! – Oleg 2010-08-08 16:14:27

1

这是我使用UDF perfered格式(似乎是要快得多还有一个大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。