oracle connect by從句中的rownum
阿新 • • 發佈:2018-11-30
在構造資料時,對於單行的基本資料來說,connect by level
與connect by rownum
可以說是等效的。比如說下面的兩個語句的結果集是一樣的。
with tab1 as (
select 'a' id, 2 num from dual
)
select*from tab1
connect by level <= 2
;
with tab1 as (
select 'a' id, 2 num from dual
)
select*from tab1
connect by rownum <= 2
;
ID | NUM |
---|---|
a | 2 |
a | 2 |
但是當基礎資料為多條時,rownum會產生不符合預期的結果。
with tab1 as (
select 'a' id, 2 num from dual union all
select 'b' id, 4 num from dual
)
select id, num, rownum rn
from tab1
connect by rownum <= 4
;
ID | NUM | RN |
---|---|---|
a | 2 | 1 |
a | 2 | 2 |
a | 2 | 3 |
a | 2 | 4 |
b | 4 | 5 |
我明明指定了rownum <= 4,卻得到了5條記錄,這是怎麼回事?
我之後又寫了多條測試語句,最終的結論是:層次查詢中的rownum與最後結果集中的rownum並不是一個。
在層次查詢中,rownum被賦予的是層次查詢中返回的結果集的序號。第一個被查詢的根節點的rownum就是1,在此基礎上,下一條返回的資料為2,以此類推。當查出第四層時,查詢結束。至於多出來的第五條資料,可以這樣理解:connect語句的結果集由兩部分組成,即由start with查詢出的根節點與connect查詢出的子節點組成。根節點是不受connect從句約束的,所以當rownum <= 4生效後,其他根節點一併歸到了結果集中。又由於oracle的層次查詢是深度優先的,所以上面的例子中,實際查出的是一顆左斜樹。這就是查出4個a和1個b的原因。
用這個語句能更清晰的看出這些特點。
with tab1 as (
select 'a' id, 2 num from dual union all
select 'b' id, 2 num from dual union all
select 'c' id, 4 num from dual
)
select id, num, rownum rn, lpad('--', level * 3, '-') || level || '_' || id path
from tab1
connect by rownum <= 4
ID | NUM | RN | PATH |
---|---|---|---|
a | 2 | 1 | —1_a |
a | 2 | 2 | ------2_a |
a | 2 | 3 | ---------3_a |
a | 2 | 4 | ------------4_a |
b | 2 | 5 | —1_b |
c | 4 | 6 | —1_c |
在這個語句的基礎上加上where rownum <= 4確實也可以只查出4條資料。
with tab1 as (
select 'a' id, 2 num from dual union all
select 'b' id, 2 num from dual union all
select 'c' id, 4 num from dual
)
select id, num, rownum rn, lpad('--', level * 3, '-') || level || '_' || id path
from tab1
where rownum <= 4
connect by rownum <= 4;
這樣可以保證只查出四條資料。
但是當語句的條件多一些後
比如這樣
with tab1 as (
select 'a' id, 2 num from dual union all
select 'b' id, 2 num from dual
)
select id, num, rownum rn, lpad('--', level * 3, '-') || level || '_' || id path
from tab1
connect by rownum <= 6
and level <= 3
;
ID | NUM | RN | PATH |
---|---|---|---|
a | 2 | 1 | —1_a |
a | 2 | 2 | ------2_a |
a | 2 | 3 | ---------3_a |
b | 2 | 4 | ---------3_b |
b | 2 | 5 | ------2_b |
a | 2 | 6 | ---------3_a |
b | 2 | 7 | —1_b |
這是預料之中的結果,但是我實在想不出什麼樣的功能會用上這種語句…