SQL 行列互变之终极方法

来源:互联网 发布:洛阳计算机编程培训 编辑:程序博客网 时间:2024/05/03 09:12

SQL之行列互变问题。
     寻寻觅觅,SQL行变列,列变行问题虽然解决方案众多,但无不存在着代码复杂,性能欠佳等问题。今有幸得知最佳解决方案,好东西不敢独享,笔记之,雅俗共赏。
     示例数据:(该示例数据来自YHHR数据库 Performance_Zmonth_Value表)
Employee_Id   Zmonth   Performance_Cd    Value      
10001         200806    A                 2.00     
10001         200806    B                 2.00      
10001         200806    C                 2.00     
10001         200806    D                 2.00     
10001         200806    E                 2.00     
10001         200806    K                 0.25     
10002         200806    A                 1.25     
10002         200806    B                 2.00      
10002         200806    C                 2.00     
10002         200806    D                 2.00     
10002         200806    K                 1.00     
10017         200806    C                 0.00     
10017         200806    D                 0.00     
10017         200806    E                 0.00     
10017         200806    K                 0.00      
10024         200806    A                 -1.00      
10024         200806    B                 0.84     
10024         200806    C                 2.00      
10024         200806    D                 2.00     
10024         200806    E                 2.00     
说明:该表存储的是每个雇员在200806月度绩效考核的分数,其中 Performance_Cd表示绩效考核的不同项
目标:要将上表“旋转”成如下传统形式:
Employee_Id   Zmonth   A     B     C     D     E     K
10001            200806    2     2     2     2     2     0.25
10002            200806    1.25 2     2     2     null  1
10017            200806    null  null  0     0     0     0    
方法:
     Select Employee_Id,Zmonth,
          Max (Case When Performance_Cd=’A’ Then Zvalue END) As A,
          Max (Case When Performance_Cd=’B’ Then Zvalue END) As B,
          Max (Case When Performance_Cd=’C’ Then Zvalue END) As C,
          Max (Case When Performance_Cd=’D’ Then Zvalue END) As D,
          Max (Case When Performance_Cd=’E’ Then Zvalue END) As E,
          Max (Case When Performance_Cd=’F’ Then Zvalue END) As F
      From Performance_Zmonth_Value
      Group by Employee_Id,Zmonth
代码简单,逻辑简单,代码性能十分高效。如果你仍然觉得代码略显复杂,在SQL2005中有更简单的解决方案。但这个简单,只是代码上的简单,经过查看两种写法的SQL执行计划,发现两种代码一模一样,性能上没有任何区别。       SELECT Employee_Id,Zmonth,A,B,C,D,E,F,K FROM Performance_Zmonth_Value PIVOT ( MAX(ZVALUE) FOR Performance_Cd                IN (A,B,C,D,E,F,K)
              )AS P;     
个人感觉,上面的代码不太好理解,因为没有明确的Group By ,所以,如果基表中有不在Select 列表中出现的列,语句在执行时会自动把这些列加到Group By中去。当然,你可以使用派生表以达到你想要的效果。
上面是列变行,下面我们来演示行变列。(以下数据来自YHHR中Employee_Counts表,该表存储各个门店岗位编制情况)
Duty_Id  [102]      [3645] [4374] [4375] [4508] [4668] [5074]
1026       5            4            4            4            4            4            4    
1043       2            1            1            1            1            0            1    
1065       1            1            1            1            1            0            1    
1074       2            2            2            2            2            2            2    
1077       1            1            1            1            1            1            1    
1079       1            1            1            1            1            1            1    
1080       27           26           24           23           20           22           22   
1081       30           28           26           25           22           22           24   
     
要将上表旋转成一下形式
Duty_Id         Store_Id         Qty
1026              102                5
1026              3645              4
1026              4374              4
1026              4375              4
运行一下代码即可 Select Duty_id,Store_Id,Qty from Employee_Counts Unpivot(Qty for Store_Id in ( [102],[3645],[4374],[4375],[4508],[4668],[5074] ) ) as p

原创粉丝点击