2015-08-25 124 views
1

我有一张代表员工及其各种详细信息的表格。我有另一张表格代表员工参加的培训课程。一些员工参加了比其他课程更多的课程。我需要在返回的查询中将每个员工表示为单个行,并提供相关详细信息和每个课程的列。动态数据透视表和加入

Employee表:

 
+--------+---------+---------+----------+ 
| EmpNum | EmpName | EmpType | EmpPhone | 
+--------+---------+---------+----------+ 
| 1234 | Smith | FT  | 09876543 | 
| 2345 | Jones | PT  | 08765432 | 
| 3456 | Brown | FT  | 07654321 | 
+--------+---------+---------+----------+ 

技能表:

 
+--------+------------+ 
| EmpNum | SkillName | 
+--------+------------+ 
| 1234 | First Aid | 
| 2345 | First Aid | 
| 3456 | First Aid | 
| 1234 | Safety  | 
| 3456 | Safety  | 
| 1234 | Leadership | 
| 2345 | Leadership | 
+--------+------------+ 

后加盟这2个表,我期待有以下返回:

 
+--------+---------+---------+----------+-----------+------------+------------+--------+ 
| EmpNum | EmpName | EmpType | EmpPhone | Skill1 | Skill2 | Skill3 | Skill4 | 
+--------+---------+---------+----------+-----------+------------+------------+--------+ 
| 1234 | Smith | FT  | 09876543 | First Aid | Safety  | Leadership |  | 
| 2345 | Jones | PT  | 08765432 | First Aid | Leadership |   |  | 
| 3456 | Brown | FT  | 07654321 | First Aid | Safety  |   |  | 
+--------+---------+---------+----------+-----------+------------+------------+--------+ 

回答

0

什么你”重新寻找是一个动态交叉表。阅读Jeff Moden的article了解更多信息。

SQL Fiddle

DECLARE @sql1 NVARCHAR(2000) = '', 
     @sql2 NVARCHAR(2000) = '', 
     @sql3 NVARCHAR(2000) = '' 

DECLARE @range INT 

--Added +1 here since you have extra Skill4 on your expected result 
SELECT TOP 1 @range = COUNT(*) + 1 
FROM Skill GROUP BY EmpNum ORDER BY COUNT(*) DESC 

SELECT @sql1 = 
'SELECT 
    e.EmpNum 
    , e.EmpName 
    , e.EmpType 
    , e.EmpPhone' + CHAR(10) 

SELECT @sql2 = @sql2 + 
' , MAX(CASE WHEN rn = ' + CONVERT(VARCHAR(3), rn) + ' THEN s.SkillName ELSE '''' END) AS ' 
    + QUOTENAME('Skill' + CONVERT(VARCHAR(3), rn))+ CHAR(10) 
FROM(
    SELECT TOP (@range) 
     ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS rn 
    FROM master..spt_values a 
)t 

SELECT @sql3 = 
'FROM(
    SELECT *, rn = ROW_NUMBER() OVER(PARTITION BY EmpNum ORDER BY (SELECT NULL)) 
    FROM Skill 
)s 
INNER JOIN Employee e 
    ON e.EmpNum = s.EmpNum 
GROUP BY 
    e.EmpNum, e.EmpName, e.EmpType, e.EmpPhone' 

PRINT(@sql1 + @sql2 + @sql3) 
EXEC (@sql1 + @sql2 + @sql3) 
+0

真棒。谢谢。 – Goolsy