分类:
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]