sqlserver 行列转换(行传换为列)

1.原始查询

SELECT s.Name AS ShiftName,
        h.BusinessEntityID,
        d.Name AS DepartmentName
FROM HumanResources.EmployeeDepartmentHistory h
INNER JOIN HumanResources.Department d
ON h.DepartmentID = d.DepartmentID
INNER JOIN HumanResources.Shift s
ON h.ShiftID = s.ShiftID
WHERE EndDate IS NULL
AND d.Name IN ('Production', 'Engineering', 'Marketing')
ORDER BY ShiftName;

 

结果如下

 

在这个结果集中,我们可以看到所有的部门都列在一个列中。下一步是将此查询返回的部门值转换为列,以及按班次计算的员工数。

想要实现的效果

 

 

2.用PIVOT关键字进行行列转换

 1 SELECT  ShiftName,        
 2                 Production,        
 3                 Engineering,        
 4                 Marketing
 5 FROM    (SELECT s.Name AS ShiftName,       
 6                             h.BusinessEntityID,      
 7                             d.Name AS DepartmentName         
 8                 FROM   HumanResources.EmployeeDepartmentHistory h                
 9                 INNER JOIN HumanResources.Department d                    
10                 ON h.DepartmentID = d.DepartmentID                
11                 INNER JOIN HumanResources.Shift s                    
12                 ON h.ShiftID = s.ShiftID         
13                 WHERE  EndDate IS NULL                
14                 AND d.Name IN ('Production', 'Engineering', 'Marketing')        
15                 ) AS a
16 PIVOT
17     ( 
18     COUNT(BusinessEntityID)
19     FOR DepartmentName IN ([Production], [Engineering], [Marketing])
20     )  AS b
21 ORDER BY ShiftName;

结果如下:

 

 

3.转换的语法如下:

 

 4.参数的定义如下:

 

官网示义

 

 

 

 

 

 

 

 

 

5.在引入PIVOT操作符之前,我们是通过以下语句进行转换的

 1 SELECT  s.Name AS ShiftName,      
 2                 SUM(CASE WHEN d.Name = 'Production' THEN 1 ELSE 0 END) AS Production,        
 3                 SUM(CASE WHEN d.Name = 'Engineering' THEN 1 ELSE 0 END) AS Engineering,       
 4                 SUM(CASE WHEN d.Name = 'Marketing' THEN 1 ELSE 0 END) AS Marketing
 5 FROM    HumanResources.EmployeeDepartmentHistory h       
 6 INNER JOIN HumanResources.Department d            
 7 ON h.DepartmentID = d.DepartmentID       
 8 INNER JOIN HumanResources.Shift s         
 9 ON h.ShiftID = s.ShiftID
10 WHERE   h.EndDate IS NULL       
11 AND d.Name IN ('Production', 'Engineering', 'Marketing')
12 GROUP BY s.Name;

也是同样结果

 

 

6.这两种方法无论是用PIVOT关键字还是直接聚合运算都需要事先知道部门的名称,因为必须要有列名,

这种情况可以先查询一下部门,然后动态拼接进column_list ,但是这种动态拼接似乎用第二种方式无法实现

 

posted on 2020-02-07 15:05  雯烈  阅读(2320)  评论(1编辑  收藏  举报