

SELECT 语句各部分执行顺序
FROM:组装来自不同数据源的数据(如实现表联结); WHERE:执行指定的筛选谓词实现上述数据的筛选; GROUP BY:数据分组;
HAVING:根据指定的聚合结果筛选分组; SELECT:从结果集中选择字段(注:a.表达式(如聚合运算等)先行计算;b.分组查询在分组前有预选字段的过程,这里SELECT从已形成的结果集中复选字段(或表达式)); DISTINCT:去重; ORDER BY:结果集排序装饰
层次查询(hierarchical query)也常被称为递归查询,属于查询语句的一个语法块,写在WHERE条件(如果有的话)的后面,ORDER语句的前面
如果一张表中的数据行与行之间存在层级关系(hierarchical data),我们则可以使用递归查询语法来展现这种层级关系
例如在EMP表中就存在着层级关系:每一行数据MGR列中的值可以追溯其他行的EMPNO列,这种数据行间的层级还原了现实世界中的职位上下隶属
CONNECT BY condition
SQL> SELECT e.ename, e.empno, e.mgr
2 FROM emp e
3 START WITH e.mgr IS NULL
4 CONNECT BY PRIOR e.empno = e.mgr;
ENAME EMPNO MGR
---------- ----- -----
KING 7839
JONES 7566 7839
SCOTT 7788 7566
ADAMS 7876 7788
FORD 7902 7566
SMITH 7369 7902
BLAKE 7698 7839
ALLEN 7499 7698
WARD 7521 7698
MARTIN 7654 7698
TURNER 7844 7698
JAMES 7900 7698
CLARK 7782 7839
MILLER 7934 7782
14 rows selected
复制
上例展示了层次查询的一个简单应用,START WITH mgr IS NULL 表示从每个 MGR 字段为空值的行开始递归,这是对现实意义中“从最高职级(具体来说就是没有上级)的人员开始查找”这种想法的解释;CONNECT BY PRIOR empno = mgr 则规定使用父行的 EMPNO 字段的值查找其子行,条件是子行的 MGR 字段值匹配该 EMPNO 值,这则是对现实意义中“上级的员工编号则是其下级人员的‘上级编号’”这种想法的代码解释
定位到 START WITH 指示的根节点; 依据 CONNECT BY 指明的关系先找到根节点下一级的子行; 每找到一层子行,便再向下检索一层,如此递进,直至所有叶子节点(没有下层的行)被找到; 如果 WHERE 条件中还有筛选性的谓语,此时 Oracle 将独立地检查上述步骤得出的结果集中的每一行,将不符合筛选条件的行舍弃; 最后 Oracle 按照从根节点到叶子节点的顺序返回结果集,子行将排列在其父行的下面; 按照语句中规定的结果集输出的排序(如果有的话)加工结果集
SQL> SELECT e.ename, e.empno, e.mgr, LEVEL
2 FROM scott.emp e
3 START WITH e.mgr IS NULL
4 CONNECT BY PRIOR e.empno = e.mgr;
ENAME EMPNO MGR LEVEL
---------- ----- ----- ----------
KING 7839 1
JONES 7566 7839 2
SCOTT 7788 7566 3
ADAMS 7876 7788 4
FORD 7902 7566 3
SMITH 7369 7902 4
BLAKE 7698 7839 2
ALLEN 7499 7698 3
WARD 7521 7698 3
MARTIN 7654 7698 3
TURNER 7844 7698 3
JAMES 7900 7698 3
CLARK 7782 7839 2
MILLER 7934 7782 3
14 rows selected
复制

SQL> -- ORDER BY 会“粗鲁地”打乱父子层次的顺序
SQL> SELECT e.ename, e.empno, e.mgr, LEVEL
2 FROM scott.emp e
3 START WITH e.mgr IS NULL
4 CONNECT BY PRIOR e.empno = e.mgr
5 ORDER BY e.empno DESC;
ENAME EMPNO MGR LEVEL
---------- ----- ----- ----------
MILLER 7934 7782 3
FORD 7902 7566 3
JAMES 7900 7698 3
ADAMS 7876 7788 4
TURNER 7844 7698 3
KING 7839 1
SCOTT 7788 7566 3
CLARK 7782 7839 2
BLAKE 7698 7839 2
MARTIN 7654 7698 3
JONES 7566 7839 2
WARD 7521 7698 3
ALLEN 7499 7698 3
SMITH 7369 7902 4
14 rows selected
SQL> -- ORDER SIBLINGS BY 仅作用于“兄弟层次”
SQL> SELECT e.ename, e.empno, e.mgr, LEVEL
2 FROM scott.emp e
3 START WITH e.mgr IS NULL
4 CONNECT BY PRIOR e.empno = e.mgr
5 ORDER SIBLINGS BY e.empno DESC;
ENAME EMPNO MGR LEVEL
---------- ----- ----- ----------
KING 7839 1
CLARK 7782 7839 2
MILLER 7934 7782 3
BLAKE 7698 7839 2
JAMES 7900 7698 3
TURNER 7844 7698 3
MARTIN 7654 7698 3
WARD 7521 7698 3
ALLEN 7499 7698 3
JONES 7566 7839 2
FORD 7902 7566 3
SMITH 7369 7902 4
SCOTT 7788 7566 3
ADAMS 7876 7788 4
14 rows selected
复制

SQL> SELECT LEVEL FROM dual CONNECT BY LEVEL <= 10;
LEVEL
----------
1
2
3
4
5
6
7
8
9
10
10 rows selected
SQL> SELECT LEVEL FROM dual WHERE LEVEL > 5 CONNECT BY LEVEL <= 10;
LEVEL
----------
6
7
8
9
10
SQL> SELECT chr(96 + LEVEL) letter FROM dual CONNECT BY LEVEL <= 26;
LETTER
------
a
b
c
d
e
f
g
h
i
j
k
l
m
n
o
p
q
r
s
t
u
v
w
x
y
z
26 rows selected
复制
注:上例中的内置函数 CHR,可以将十进制的 ASCII 码转换成对应的字符
文章转载自SQL干货分享,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。