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. 1       8800    8420    7812
  13. 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. insert into score values
  9. (1, '语文', 8800),
  10. (1, '数学', 8420),
  11. (1, '英语', 7812),
  12. (2, '语文', 8715),
  13. (2, '数学', 8511),
  14. (2, '英语', 8512)
  15. go
  16. select banji,
  17. max(yuwen)        语文,
  18. max(shuxue)       数学,
  19. max(yingyu)       英语
  20. from
  21. (select  banji,
  22. case kemu
  23. when '语文' then fengshu
  24. else 0
  25. end                         yuwen,
  26. case kemu
  27. when '数学' then fengshu
  28. else 0
  29. end                         shuxue,
  30. case kemu
  31. when '英语' then fengshu
  32. else 0
  33. end                         yingyu
  34. from score
  35. ) as inner
  36. group by inner.banji
  37. order by 1
  38. 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子句中的一个表产生了关系,取出了表中的一列作为数据.

DB2行转列、列转行等操作的更多相关文章

  1. 微软BI 之SSIS 系列 - 在 SQL 和 SSIS 中实现行转列的 PIVOT 透视操作

    开篇介绍 记得笔者在 2006年左右刚开始学习 SQL Server 2000 的时候,遇到一个面试题就是行转列,列转行的操作,当时写了很长时间的 SQL 语句最终还是以失败而告终.后来即使能写出来, ...

  2. SQL Server 行转列,列转行。多行转成一列

    一.多行转成一列(并以","隔开) 表名:A 表数据: 想要的查询结果: 查询语句: SELECT name , value = ( STUFF(( SELECT ',' + va ...

  3. Sql server 中将数据行转列列转行(二)

    老规矩,先弄一波测试数据,数据填充代码没有什么意义,先折叠起来: /* 第一步:创建临时表结构 */ CREATE TABLE #Student --创建临时表 ( StuName ), --学生名称 ...

  4. db2 将原表列notnull属性修改为null属性的方法 (查看主键约束,唯一约束去syscat.tabconst)

    好久没机会写点东西了,今天把自己遇到的一个小问题跟大家分享一下如何修改db2数据库表中列的属性--将列的非空属性改为允许空的属性,修改数据表的某一列属性其实很简单但是里面有需要细节需要dba注意,毕竟 ...

  5. db2将原表列notnull属性修改为null属性的方法

    今天把自己遇到的一个小问题跟大家分享一下如何修改db2数据库表中列的属性--将列的非空属性改为允许空的属性,修改数据表的某一列属性其实很简单但是里面有需要细节需要dba注意,毕竟数据的安全才是最重要的 ...

  6. Oracle 多行变一列的方法

    多行变一列的方法有很多,觉得这个第一眼看懂了当时就用的这个办法. 情况是这样的.以下数据前几列是一样的,需要把VAT_VALUE_CHAR 的值放在同一行上. SELECT * FROM ps_vat ...

  7. 用VBA计算WPS 表格ET EXCEL中的行数和列数的多重方法

    用VBA计算WPS 表格ET EXCEL中的行数和列数 每种方法中上面的是Excel的行数,下面的是Excel的列数. 方法1: ActiveSheet.UsedRange.Rows.Count Ac ...

  8. C# 对Excel 单元格格式, 及行高、 列宽、 单元格边框线、 冻结设置

    一.对行高,列宽.单元格边框等的设置 这篇简短的文字对单元格的操作总结的比较全面,特此转载过来. private _Workbook _workBook = null; private Workshe ...

  9. VBA取得EXCEL表格中的行数和列数

    VBA取得EXCEL表格中的行数和列数 初学EXCEL宏的童鞋,总是很想知道表格中含有数据的行数和列数,尤其是行数和列数不确定的情况下.这样可以避免很多的错误,并且可以提高效率.但每次用到的时候到网上 ...

随机推荐

  1. copy-mutableCopy

    copy和mutableCopy语法的目的:改变副本的时候,不会影响到源对象:调用Copy产生的对象是不可变的,调用mutableCopy产生的对象是可变的,与调用对象是否可变无关. Copy 需要先 ...

  2. ubuntu 下root用户无法访问声音设备的解决方案

    原因:root用户没有对pulsaudio的访问权限,而且pulsaudio默认是不能在root下自动启动解决办法: 一.修改自动启动:编辑 gedit /etc/default/pulseaudio ...

  3. VLC编译问题

    在Ubuntu下编译VLC源代码生成的VLC无法播放Youtube视频(比如https://www.youtube.com/watch?v=mDp-ABzpRX8) 错误提示如下: zlf@ubunt ...

  4. 02.Apache FtpServer使用数据库管理用户

    1.创建数据库及表 使用\apache-ftpserver-1.0.6\res\ftp-db.sql建表,内容如下: CREATE TABLE FTP_USER ( userid VARCHAR(64 ...

  5. jquery如何删除一个元素后面的所有元素

    $("div>span:first").nextAll().remove()

  6. Hibernate中查询数据转成VO对象及注意问题

    大家都可能会遇到,在用json传输数据时,很多字段是来自不同的表数据,需要我们进行封装数据. hibernate提供这么一个方法用来直接封装查询属性: query.setResultTransform ...

  7. GameMap(类结构)(不断跟新)

    暂时有个疑问为什么这些需要这么复杂的继承

  8. vector存入共享内存(了解)

    昨天在上篇blog里描写了如何把STL容器放到共享内存里去,不过由于好久不写blog,发觉词汇组织能力差了很多,不少想写的东西写的很零散,今天刚好翻看自己的书签,看到一篇挺老的文章,不过从共享内存到S ...

  9. 【五】PHP数组操作函数

    1.输出数组的结构:bool print_r(数组); $arr=array('jack','mike','tom'); print_r($arr);//Array ( [0] => jack ...

  10. IDEA开发spark本地运行

    1.建立spakTesk项目,建立scala对象Test 2.Tesk对象的代码如下 package sparkTest /** * Created by jiahong on 15-8-2. */ ...