DB2行转列、列转行等操作

DB2 行转列

----start

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

[c-sharp] view plaincopyprint?

  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语句创造虚拟字段,使结果集成为二维数组,然后应用聚合函数返回单一记录。怎么样?不理解,仔细看看下面的图和分析下面的语句你就理解了。

[c-sharp] view plaincopyprint?

  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 Q4FROM SalesGROUP 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.ResultsFROM 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子句中的一个表产生了关系,取出了表中的一列作为数据.

时间: 2024-10-13 01:02:09

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

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

开篇介绍 记得笔者在 2006年左右刚开始学习 SQL Server 2000 的时候,遇到一个面试题就是行转列,列转行的操作,当时写了很长时间的 SQL 语句最终还是以失败而告终.后来即使能写出来,也是磕磕碰碰的,虽然很能锻炼 SQL 功底,每次都要挣扎一番,溺水的感觉.记得SQL Server 2005 以后就有了 PIVOT 和 UNPIVOT 这两个函数,可以非常方便的实现行转列和列传行的操作,就不再那么挣扎了.后来,在一个 08 项目中,有一位新的女同事在改一个 ETL,发现 SSIS

数据库 行转列 列转行详解

目录结构如下: 行转列 列转行 [一].行转列 1.1.初始测试数据 表结构:TEST_TB_GRADE create table TEST_TB_GRADE ( ID        NUMBER(10) not null, USER_NAME VARCHAR2(20 CHAR), COURSE    VARCHAR2(20 CHAR), SCORE     FLOAT ) [sql] view plaincopy create table TEST_TB_GRADE ( ID        N

MSSQLServer 纵向表转横向表 横向表转纵向表 行转列 列转行

MSSQLServer 纵向表转横向表  横向表转纵向表 建表语句及插入数据语句: CREATE TABLE Test_y( [Name] [nchar](10) NULL, [Course] [nchar](10) NULL, [Grade] [int] NULL ) insert into Test_y values ('张三','语文',75); insert into Test_y values ('张三','数学',80); insert into Test_y values ('张三

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

老规矩,先弄一波测试数据,数据填充代码没有什么意义,先折叠起来: /* 第一步:创建临时表结构 */ CREATE TABLE #Student --创建临时表 ( StuName nvarchar(20), --学生名称 Chinese int, Math int, English int ) DROP TABLE #Student --删除临时表 SELECT * FROM #Student --查询所有数据 INSERT INTO #Student(StuName,Chinese,Math

如何在一个实例下并存行存储和列存储数据库

相关概念 BLU Acceleration BLU Acceleration 是 DB2 10.5 最新特性,与传统的行存储数据方式不同,数据是按照列来进行组织存储的,即采用列式存储.BLU 除了列存储表特性外,它的数据跳读,SIMD 和类哈弗曼的压缩算法等特性方便在内存中完成数据处理,简化并且加速了数据分析的工作量.同时不再需要索引.MQT 等,这样易于实施并可以自行调优,提高了 CPU 的使用率,以及降低了 IO. IBM Data Server Manager IBM 最新推出的管理多种平

Oracle 多行变一列的方法

多行变一列的方法有很多,觉得这个第一眼看懂了当时就用的这个办法. 情况是这样的.以下数据前几列是一样的,需要把VAT_VALUE_CHAR 的值放在同一行上. SELECT * FROM ps_vat_defaults defaults WHERE defaults.vat_driver = 'VAT_ENT_RGSTRN' AND defaults.vat_driver_key1 = 'AMB19' AND defaults.vat_driver_key2 = 'DEU' AND vat_de

如何快速选中某单元格所在的整行或整列 Excel教程

我们可以使用快捷键的操作来快速选中B3单元格所在的整行或整列,操作方法如下,请大家参阅! 一.正规的快捷键操作 ①快速选中整行 按下键盘上的 Shift Space 即同时按下键盘上的Shift 空格键,这样,就能快速选中B3所在行的整行了. 操作方法注意,可先按下Shift不放,再按下空格键,这样更容易选中整行. ②快速选中整列 按下键盘上的 Ctrl Space 即同时按下键盘上的Ctrl 空格键,这样,就能快速选中B3所在行的整列了. 操作方法注意,可选按下Ctrl不放,再按下空格键,这样

行数据库VS列数据库

一.介绍 目前大数据存储有两种方案可供选择:行存储和列存储.业界对两种存储方案有很多争持,集中焦点是:谁能够更有效地处理海量数据,且兼顾安全.可靠.完整性.从目前发展情况看,关系数据库已经不适应这种巨大的存储量和计算要求,基本是淘汰出局.在已知的几种大数据处理软件中,Hadoop的HBase采用列存储,MongoDB是文档型的行存储,Lexst是二进制型的行存储. 顾名思义,这两种数据库架构在存贮数据时的方式是大相径庭的.在行式数据库中,每一行中的每一块数据都是紧挨着另一块数据存放在硬盘中.一般

一起talk C栗子吧(第一百七十五回:C语言实例--获取当前终端的行数和列数)

各位看官们,大家好,上一回中咱们说的是关闭终端中缓冲功能的例子,这一回咱们说的例子是:获取当前终端的行数和列数 .闲话休提,言归正转.让我们一起talk C栗子吧! 看官们,我们在前面章回中介绍了termios相关的信息,以及termios提供的编程接口,通过这些接口可以操作终端,今天我们再介绍一些操作终端的编程接口,通过这些接口可以获取当前终端的行数和列数,这便是我们今天的主题. int setupterm(char *term, int fd, int *errret); 该函数用来修改当前