拼吾爱程序人生

首页 » 数据库编程 » SQL » SQL之行列互变问题
cobra - 2008-7-28 2:02:00
文/zhouqiang52154  出处/博客园

SQL之行列互变问题。

    SQL行变列,列变行问题虽然解决方案众多,但大多存在着代码复杂,性能欠佳等问题。

    示例数据:

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) As A,

          Max (Case When Performance_Cd=’B’ Then Zvalue) As B,

          Max (Case When Performance_Cd=’C’ Then Zvalue) As C,

          Max (Case When Performance_Cd=’D’ Then Zvalue) As D,

          Max (Case When Performance_Cd=’E’ Then Zvalue) As E,

          Max (Case When Performance_Cd=’F’ Then Zvalue) 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中去。当然,你可以使用派生表以达到你想要的效果。



上面是列变行,下面我们来演示行变列。(以下数据表存储各个门店岗位编制情况,[102],[3645]等即是列名,又是分店ID)

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





运行以下代码即可(该代码只适合SQL2005)

Select Duty_id,Store_Id,Qty

from Employee_Counts

Unpivot(Qty for Store_Id in (

[102],[3645],[4374],[4375],[4508],[4668],[5074]

)

) as p

 您可能对 [SQL] 的这些文章也感兴趣:

使用存储过程实现分页打印
SELECT语句中的*号不为人知的其他作用
数据库查询结果的动态排序(4)
将一个表分开导出成不同文件的实用方法
巧用SQL的全局临时表防止用户重复登录
通过分析SQL语句的执行计划优化SQL(三)
使用Dynamic.cs动态构造Lambda 表达式
NHibernate系列(4):探索查询之条件查询(Criteria Query)
NHibernate系列(2):第一个NHibernate程序
IBatis.Net学习系列
1
查看完整版本: SQL之行列互变问题
Modify by pin5i DZNT_ExpandPackage 2.1.3237 2007-2008 pin5i.com
  Total Unique Visitors: