Chinaunix首页 | 论坛 | 博客
  • 博客访问: 681514
  • 博文数量: 845
  • 博客积分: 5000
  • 博客等级: 大校
  • 技术积分: 5015
  • 用 户 组: 普通用户
  • 注册时间: 2008-10-15 16:22
文章分类

全部博文(845)

文章存档

2011年(1)

2008年(844)

我的朋友

分类:

2008-10-15 16:25:57

        1. 11g以前的行列转换

        领袖又说了:“温故而知新”。那就让我们先看看11g以前是怎么实现地。行列转换一直当作甄别老手和新手的试金石,面试的时候面试官不问这个都不好意思张嘴。Itpub的开发版更是每隔十天半个月就有人问这个,你说重要不重要。

        假设有表emp_phone如下:

NAME
TYPE
PHONE
张三
1
1234-5678
张三
2
4567-7890
张三
3
6000-1001
李四
1
2123-1237
李四
3
6001-5600
马五u
1
3248-1378
马五
2
3423-3948
王二(没麻子)
2
2890-1245
。。。
 
 

        表里放着张三李四王二麻子等等主人翁的电话号码。(TYPE 1/2/3分别对应家/办公室/手机)。如果要把每个人的所有电话放在一行上,就是行转列了。结果如下:

NAME
HOME
OFFICE
MOBILE
张三
1234-5678
4567-7890
6000-1001
李四
2123-1237
 
6001-5600
马五
3248-1378
3423-3948
 
王二(没麻子)
 
2890-1245

        写这个SQL的技巧就是按姓名分组,然后使每一组每一类的电话号码最多只有一个,里边用到的分组函数都是聋子的耳朵-摆设。用MAX可以,MIN也行。

        这个查询写出来就是:

         SELECT
        name,
        MAX(decode(type, 1, phone)) Home,
        MAX(decode(type, 2, phone)) Office,
        MAX(decode(type, 3, phone)) Mobile
        FROM
        emp_phone
        GROUP BY
        Name
        /

        那位看官说了:“能不能再变回去?”能,不能戏法不就漏了不是?

        这儿要用到另一的技巧就是笛卡尔乘积,将一行复制成三行,每一行取一个类型的电话

        偷个懒儿把上边的结果表叫emp_phone_x,把列还原成行的SQL:

         SELECT
        NAME,
        DECODE (lvl, 1, home, 2, office, 3, mobile) phone
        FROM
        emp_phone_x,
        (SELECT LEVEL lvl
        FROM DUAL
        CONNECT BY LEVEL <= 3)
        WHERE
        DECODE (lvl, 1, home, 2, office, 3, mobile) IS NOT NULL /

[1]  

【责编:michael】

--------------------next---------------------

阅读(297) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~