• DB2行转列、列转行等操作


    DB2 行转列

    ----start

    在网上看到这样一个问题:(问题地址:http://www.mydb2.cn/bbs/read.php?tid=1297&page=e&#a

    1. 班级  科目   分数  
    2. 1     语文   8800  
    3. 1     数学   8420  
    4. 1     英语   7812  
    5. ……  
    6. 2     语文   8715  
    7. 2     数学   8511  
    8. 2     英语   8512  
    9. ……  
    10.    
    11.    
    12. 要求转换成下面这样的结果  
    13. 班级    语文    数学    英语  
    14. 1       8800    8420    7812  
    15. 2       8715    8511    8512  

    这是一个非常经典的 4属性的表设计模式,顾名思义,这样的表一般有四列,分别是:entity_id, attribute_name,attribute_type, attribute_value ,这样的设计使我们添加字段非常容易,如:我们想添加一个物理成绩是非常简单的,我们只要向表中插入一条记录即可。但是,这样的设计有一个非常严重的问题,那就是:查询难度增加,查询效率非常差。

    要想实现上面的查询有一个原则,那就是:通过case语句创造虚拟字段,使结果集成为二维数组,然后应用聚合函数返回单一记录。怎么样?不理解,仔细看看下面的图和分析下面的语句你就理解了。

    1. create table score  
    2. (  
    3.     banji integer,  
    4.     kemu varchar(10),   
    5.     fengshu integer  
    6. )  
    7. go  
    8.    
    9. insert into score values  
    10. (1, '语文', 8800),  
    11. (1, '数学', 8420),  
    12. (1, '英语', 7812),  
    13. (2, '语文', 8715),  
    14. (2, '数学', 8511),  
    15. (2, '英语', 8512)  
    16. go  
    17.    
    18. select banji,  
    19.        max(yuwen)        语文,  
    20.        max(shuxue)       数学,  
    21.        max(yingyu)       英语  
    22. from    
    23.      (select  banji,  
    24.               case kemu  
    25.                when '语文' then fengshu  
    26.                else 0  
    27.              end                         yuwen,  
    28.              case kemu  
    29.                when '数学' then fengshu  
    30.                else 0  
    31.              end                         shuxue,  
    32.              case kemu  
    33.                when '英语' then fengshu  
    34.                else 0  
    35.              end                         yingyu  
    36.       from score  
    37.       ) as inner  
    38. group by inner.banji  
    39. order by 1  
    40. go  

    你可能正在感叹,这样的解决方案是多么的巧妙,可惜不是我想出来的,在这里,我也不敢把大师的思想据为己有,以上思想来自<SQL语言艺术>的第11章,想了解更全面的信息,大家可以参考。

    ---更多参见:DB2 SQL 精萃

    ----声明:转载请注明出处。

    ----last updated on 2009.12.20

    ----written by ShangBo on 2009.12.16

    ----end

    DB2 列转行

    行转列

    给出下面的数据:
    CREATE TABLE Sales (Year INT, Quarter INT, Results INT)

    YEAR        QUARTER     RESULTS
    ----------- ----------- -----------
    2004 1 20
    2004 2 30
    2004 3 15
    2004 4 10
    2005 1 18
    2005 2 40
    2005 3 12
    2005 4 27
    想要的到结果:
    YEAR Q1 Q2 Q3 Q4
    ----------- ----------- ----------- ----------- -----------
    2004 20 30 15 10
    2005 18 40 12 27
    这个SQL就可解决这个问题:
    SELECT Year,
    MAX(CASE WHEN Quarter = 1
    THEN Results END) AS Q1,
    MAX(CASE WHEN Quarter = 2
    THEN Results END) AS Q2,
    MAX(CASE WHEN Quarter = 3
    THEN Results END) AS Q3,
    MAX(CASE WHEN Quarter = 4
    THEN Results END) AS Q4
    FROM Sales
    GROUP BY Year
    解释一下为什么要加max的原因,因为不加max的话结果会是这样:
    YEAR Q1 Q2 Q3 Q4
    ----------- ----------- ----------- ----------- -----------
    2004 20 - - -
    2004 - 30 - -
    2004 - - 15 -
    2004 - - - 10
    2005 18 - - -
    2005 - 40 - -
    2005 - - 12 -
    2005 - - - 27


    列转行

    给出下面数据

    CREATE TABLE SalesAgg
    ( year INTEGER,
    q1 INTEGER,
    q2 INTEGER,
    q3 INTEGER,
    q4 INTEGER );

    YEAR Q1 Q2 Q3 Q4
    ----------- ----------- ----------- ----------- -----------
    2004 20 30 15 10
    2005 18 40 12 27

    想要的结果
    YEAR QUARTER RESULTS
    ----------- ----------- -----------
    2004 1 20
    2004 2 30
    2004 3 15
    2004 4 10
    2005 1 18
    2005 2 40
    2005 3 12
    2005 4 27

    这个SQL就可以实现:

    SELECT S.Year, Q.Quarter, Q.Results
    FROM SalesAgg AS S,
    TABLE (VALUES(1, S.q1),
    (2, S.q2),
    (3, S.q3),
    (4, S.q4))
    AS Q(Quarter, Results);
    每个values中对应列的数据类型必须相同,值可以任意,如1,2,3,4都是整形

    下面解释一下执行的过程:
    核心是用table函数创建了一个表,这个表是用value实现的多行表,value实现虚表的例子:

    db2 => select * from (values (1,2),(2,3)) as t1(col1,col2)

    COL1 COL2
    ----------- -----------
    1 2
    2 3

    2 条记录已选择。

    db2 => select * from (values 1) as a

    1
    -----------
              1

    1 条记录已选择。

    所不同的是这里跟from子句中的一个表产生了关系,取出了表中的一列作为数据.

  • 相关阅读:
    vue项目的骨架及常用组件介绍
    细谈最近上线的Vue2.0项目(一)
    【请求之密】payload和formData有什么不同?
    【19道XSS题目】不服来战!
    Hexo+Coding搭建免费博客之Hexo代码上传到Coding实现公网访问站点(三)
    Hexo+Coding搭建免费博客之Next主题设置(二)
    Hexo+Coding搭建免费博客之Hexo安装部署(一)
    Openstack-Queens详细安装教程
    ESXI安装报错,No Network adapters were detected...
    VMware ESXi 5.5组件安装过程记录
  • 原文地址:https://www.cnblogs.com/Rozdy/p/5010419.html
Copyright © 2020-2023  润新知