level是在树形结构中、表示层级的伪列。
Oracle支持树形结构的查询,用关键字connect by 表示。
connect by表示在构造树形结构时,上下级的确定方式或者用来查找下(上)级记录的条件,满足这个条件就拼到结果树里。
默认是从根开始,如connect by prior id=pid,表示构造树时,本记录的id是下条的pid,即找pid=本条id的记录做下条记录。
交换prior位置,表示从叶开始。如connect by id= prior pid,表示构造树时,本记录的pid是下条的id。
ps:prior表示构造树的源头方向。
因为level只在树形结构中,所以level必须与connect by 结对出现。
实质是递归方法。
select level from dual connect by level<=5;
原理说明:
1.dual只有1条记录,所以构造树时,每层都只有1个记录,level不会重复;
2.构造条件是:level<=5,所以截止到5。
由场景1的推演,可以是日期、月份等,步长也可以调整。
select sysdate+level from dual connect by level<=5;
是树查询与正则表达式的完美结合。
如,要把[a,b,22]按逗号拆解开。
SELECT REGEXP_SUBSTR('a,b,22', '[^,]+', 1, LEVEL)
FROM DUAL
CONNECT BY REGEXP_SUBSTR('a,b,22', '[^,]+', 1, LEVEL) IS NOT NULL
原理说明:
1.dual只有1条记录,所以构造树时,每层都只有1个记录,可能形成了包含本记录的n次不同level的重复。
2.connect by条件:按层级截取表达不能为空,因为只有3个元素,所以只到3级。
3.正则表达式的含义:
如图,把区间表达式1-5,拆解成1,2,3,4,5。
with temp0 as
(select t.range_num,
REGEXP_SUBSTR(t.range_num, '[^-]+', 1, 1) minNum, --最小num
REGEXP_SUBSTR(t.range_num, '[^-]+', 1, 2) maxNum --最大num
from (select '1-5' as range_num
from dual
union
select '6-9' as range_num
from dual) t)
select t1.range_num, t2.lv
from temp0 t1
join (select level lv
from dual
CONNECT BY LEVEL <= (select max(maxNum) from temp0)) t2
on (t2.lv >= t1.minNum and t2.lv <= t1.maxNum);
原理说明:
1.用正则表达式,拆解出范围的最大、最小值。如1-5对应1,5;
2.用connect by 构造范围对应的集合。本例最大值是9,顾是1,2,3…9
3.用表连接构造最终结果。连接条件:t2.lv >= t1.minNum and t2.lv <= t1.maxNum。