|
又看了一些,再提一些意见或补充:
5)找出每个部门的经理
这个需求,我们可以从树中查找,也就是对于每个部门选最高等级节点。可以使用connect
by后加条件过滤branches 的方法。
select level,a.* from
s_emp a
start with manager_id is null
connect by prior id=manager_id and dept_id !=prior dept_id;--当前行的dept_id不等于前一行的
dept_id,即每个子树中选最高等级节点
这个SQL和需求“找出每个部门的经理”没什么关系。找出来的可能有很多非经理。
6)查询一个组织中最高的几个等级
用where level条件过滤
select level,a.* from
s_emp a
where level <=2 –查找前两个等级
start with manager_id is null
connect by prior id=manager_id and dept_id !=prior dept_id;
这个需求把LEVEL<=2放到CONNECT BY中会更高效,因为尽早截断遍历路径。
8)找出指定层次中的叶子节点
Leaf(叶子)就是没有子孙的孤立节点。Oracle 10g提供了一个简单的connect_by_isleaf=1,
0 表示非叶子节点
select level,id,manager_id,last_name, title from s_emp
where connect_by_isleaf=1 –表示查询叶子节点
start with manager_id=2
connect by prior id=manager_id;
Oracle advanced sql by dj mailto:dingjunlove@163.com
第 27 页 共 90 页
也可以通过连接查询获得,方法有多种,叶子节点肯定是level最大的节点。
select a.lev,b.id from (
select max(level) lev from s_emp --查询最大的level
start with manager_id=2
connect by prior id=manager_id) a,
(select level lev,id
from s_emp
start with manager_id=2
connect by prior id=manager_id) b
where a.lev=b.lev;
这方法有问题,因为子树可能不是等高的。矮树的叶子LEVEL较小。
5.3.4 CONNECT_BY_ROOT
9i办法:用SYS_CONNECT_BY_PATH, 然后用INSTR, SUBSTR把第一截解析出来。
5.3.5 使用SIBLINGS关键字排序
9i 办法:
SELECT ... FROM
(SELECT ...
,SYS_CONNECT_BY_PATH(LPAD(PAPRENT_ID,20)||LPAD(ORDER_BY_表达式,20),'\') AS sorting ----- LPAD用于对齐,如果LPADORDER_BY_表达式是字符串,则第二个LPAD不用;如果是日期、时间先TO_CHAR转换为 YYYYMMDDHH24MISS
FROM ...
START WITH ....
CONNECT BY ....
)
ORDER BY sorting
1、 固定列数的行列转换
如
name subject grade
---------------------------
student1 语文 80
student1 数学 70
student1 英语 60
student2 语文 90
student2 数学 80
student2 英语 100
……
转换为
语文 数学 英语
student1 80 70 60
student2 90 80 100
按照name分组得到的结果,所以decode外面要套个sum,不然group by出现语义错误,
结果为
select name,sum(decode(subject,'语文', grade,null)) "语文",
sum(decode(subject,'数学', grade,null)) "数学",
sum(decode(subject,'英语', grade,null)) "英语"
from student
group by name
最好用MAX或MIN不要用SUM, 这样也适用于非NUMBER型的行转列。
|
|