Oracle10g中新型层次查询选项简介

上一篇 / 下一篇  2008-01-29 21:29:58 / 个人分类:转载

Oracle10g中新型层次查询选项简介

我们可以通过START WITH......CONNECT BY...子句来实现SQL的 层次查询,而Oracle 10g 为其添加许多了新的伪列。 ITPUB个人空间!jnp IXf2r+Y

  我们可以通过START WITH . . . CONNECT BY . . .子句来实现SQL的 层次查询,而Oracle 10g 为其添加许多了新的伪列。十多年以来,Oracle SQL 具有依照层次关系进行查询的 < 功能。例如,你可以指定一个起始条件,然后根据一个或多个连接条件来确定孩子行的内容。举例来说,现在假设我有一个表,里面记录了世界上的某些地区,其表结构如下:>

 

create table hierITPUB个人空间W$c2Ms/}Do.D
ITPUB个人空间cfK(HX:m7M2^
(ITPUB个人空间[5Q!N YrKPs

iP8zX[ER3~100788parent varchar2(30),
*m-M d,T2SG~2J100788ITPUB个人空间k5A"?4i2y u ^7HTc
child varchar2(30)ITPUB个人空间 r,`PO0D2Nq;v(o

/~]I G |Ol100788);
2o u2k&x$l]y5C~100788
5Q&]ErV1^100788insert into hier values(null,'Asia');
oW@o_&A _S100788ITPUB个人空间m3Y:FO6kZi|
insert into hier values(null,'Australia');
)b;lOg(`{ JM(x"]100788
|Q-h.G^n100788insert into hier values(null,'Europe');ITPUB个人空间!x5RL$Yx y

5?8e3J m+d+hp100788insert into hier values(null,'North America');
E2hFyCe100788ITPUB个人空间:C?TMt ~
insert into hier values('Asia','China');
;uk%ii{#uR{2M100788
.uvW rn)u K.F(Y100788insert into hier values('Asia','Japan');
uih|:J9R.^]u100788
h7~)HA|$C2XQ@100788insert into hier values('Australia','New South Wales');ITPUB个人空间$IU]%I@;x)Q

I? w9Ek HG(s100788insert into hier values('New South Wales','Sydney');ITPUB个人空间7|o+yl)f"v:`O3A+v
ITPUB个人空间^3^(X&L6@[:UcE%X
insert into hier values('California','Redwood Shores');
M.kk G[100788
vj pmD100788insert into hier values('Canada','Ontario');ITPUB个人空间*GA9e J9M8oH%J

1w BLr*p4E4n100788insert into hier values('China','Beijing');ITPUB个人空间a4d-U'X-c6u T
ITPUB个人空间NhX,C"\8T
insert into hier values('England','London');
i/rkl.}(L)R$p O100788ITPUB个人空间|p0E;bG(O/gCT
insert into hier values('Europe','United Kingdom');
Ui |.a@ jl5k)@#c5R100788
v$b[+R;H4a Du@(Z100788insert into hier values('Japan','Osaka');ITPUB个人空间+a8Ks l k^_]Gv
ITPUB个人空间N&U Se]/SlC
insert into hier values('Japan','Tokyo');ITPUB个人空间 w*FA4?;g$s1r

w%S#?2| i%uC C100788insert into hier values('North America','Canada');ITPUB个人空间SxP y$C8R
ITPUB个人空间)P2| yNzlRIC)r
insert into hier values('North America','USA');
n#U&{"|l Vh100788ITPUB个人空间;x5bL*n6R[.ebH!U]
insert into hier values('Ontario','Ottawa');ITPUB个人空间 C/unC;X wC;w
ITPUB个人空间!L2q%]i|F+S3E2Fy8^
insert into hier values('Ontario','Toronto');ITPUB个人空间S;_2[.c!?y"Q

W0R?Y:k` y100788insert into hier values('USA','California');ITPUB个人空间"z%}+k ]'A'pW"We m
ITPUB个人空间.cuD2jog@R-GW;KC
insert into hier values('United Kingdom','England');

  那么我们可以使用START WITH . . . CONNECT BY . . .从句将父级地区与孩子地区连接起来,并将其层次等级显示出来。

column child format a40
!C;s uVMP%J100788
i,x-K,L\dC100788select level,lpad(' ',level*3)||child childITPUB个人空间$H/VM3|vJ3O

CM;Q'Y})yh@100788from hier
;^O$ck5C`Q)N;G100788ITPUB个人空间M*U%|ez1H
start with parent is null
,T]"oQ8B100788
8n{|c}u Z100788connect by prior child = parent;ITPUB个人空间R(r)t(i:R
ITPUB个人空间 d?A5X!ToW C5E
LEVEL CHILD
7i o7{t&f~m&s[100788ITPUB个人空间7a)P2Yht*E8ljuU
---------- --------------------------
nk0^!eK*Y6He;}W100788
"j&F-y0FzX;M1007881 Asia
,R0VB8S,H"V u9c100788ITPUB个人空间U a J l a:@'Z
2 ChinaITPUB个人空间*v-b%S^*U*o

$N|t })I1007883 BeijingITPUB个人空间1C`Oy-RXw

3@-e9`3f0zIT1007882 Japan
u/{zeU#e9]ok100788ITPUB个人空间u,r)b'?g
3 Osaka
F F#hG Ip5fr$J100788
vvkll0je3Kt$w1007883 TokyoITPUB个人空间Ui(@VYo
ITPUB个人空间l`6|Nv}8aq"jK
1 Australia
$E ^+n\8p%q100788ITPUB个人空间/n y0@y?A*F/|l_
2 New South WalesITPUB个人空间|;w)OPe-eO4h;p

5{|h \&pUi1007883 Sydney
an;A`%u5XzWky100788ITPUB个人空间.QU G0Asa
1 Europe
QO7uM&U/\H/w;P Ng100788
*pBmv?WDA,t1007882 United KingdomITPUB个人空间.n2^+]f9@+z
ITPUB个人空间:p"~$VvYP
3 England
^"|,sANk]100788
q i+lG[1007884 LondonITPUB个人空间6UXL'r'Z$IB
ITPUB个人空间q!k"hOHPA
1 North AmericaITPUB个人空间#mN5[CGsQ#t{]4z

g8kKd@E5}Y1007882 CanadaITPUB个人空间!H9L+^;OU,uw
ITPUB个人空间7a%R3SY?u
3 Ontario
!r2nt$rA100788
S O/Tr:i,NI6J1007884 Ottawa
s:ex:RAR6G100788
v`fr?*j.b,_!x1007884 TorontoITPUB个人空间1\9p!L!M0M_ a6K
ITPUB个人空间F'l ~'fo _ _
2 USA
[g"EKWgKS100788
*m BGC^ sB+F[1007883 CaliforniaITPUB个人空间id*A @gR9J

?*gqF'y$D'x3z7G)C1007884 Redwood Shores

  自从Since Oracle 9i 开始,就可以通过 SYS_CONNECT_BY_PATH 函数实现将从父节点到当前行内容以“path”或者层次元素列表的形式显示出来。 如下例所示:

column path format a50
x8H^B3t ^&H100788ITPUB个人空间n#\*RLz
select level,sys_connect_by_path(child,'/') pathITPUB个人空间$s9X3ls"ymY(Z5o:^

D w#fbB7C ^"LU100788from hierITPUB个人空间d,BZ8d9O

5lb_uUy9XJ100788start with parent is null
n6lA9M*c-WS100788
-_ d5qQ4LlU100788connect by prior child = parent;ITPUB个人空间yE|/F/[u7}-exI D
ITPUB个人空间7tO0n7o+n_Kc*s
LEVEL PATH
#D~Vu.KLxa100788
7v5X%tc/f@100788-------- --------------------------------------------
W:hT"v(m-g}100788ITPUB个人空间Rg;N7g%B&C]
1 /AsiaITPUB个人空间D:c7brur
ITPUB个人空间0p2H+n$Y+B(B&OE
2 /Asia/ChinaITPUB个人空间R%N}Nn"nB

t]1l$`7l7^;Ox e1007883 /Asia/China/Beijing
#A?Z}z3?8GI100788ITPUB个人空间!v,cyny
2 /Asia/JapanITPUB个人空间+j2zb'Ih#o DB

x mv%b\DB1007883 /Asia/Japan/Osaka
E'Y {B)o:uH~y;v.j100788ITPUB个人空间i0Q8rL&?Q/^6gA
3 /Asia/Japan/Tokyo
%CsQkA*F5U~6`100788
G4V'] u$}Z.Y |qS1007881 /Australia
},EEW,A9l100788ITPUB个人空间g'hh.f~L(Ev
2 /Australia/New South WalesITPUB个人空间/h)[? k#G4\6o
ITPUB个人空间A f.y9Q&T;tX:JP b
3 /Australia/New South Wales/SydneyITPUB个人空间 K9j;k O(C9d%O3[uX
ITPUB个人空间6^g _$u(jj
1 /Europe
0X3V`|.q#g6k:e100788
6?[,wJw,p9I,~pMu;j1007882 /Europe/United KingdomITPUB个人空间GXe4R)o2N(m[s4~*S

;H+U1P/~I/`8}kH7n*o1007883 /Europe/United Kingdom/EnglandITPUB个人空间/NiEp2^ u)AkpG"v-q

X8M i-iy#Gh1007884 /Europe/United Kingdom/England/LondonITPUB个人空间#}7RLG@)bv&k

*\G rB9p4E1007881 /North America
0]UqRj-rWN/SB2_100788ITPUB个人空间(YIK:Hnfq
2 /North America/Canada
-U9rn2E#f1o[!Hfiv100788ITPUB个人空间*e"E,J%d)L;bI
3 /North America/Canada/OntarioITPUB个人空间 [\Z7HO3p
ITPUB个人空间5D%j/psk#i
4 /North America/Canada/Ontario/Ottawa
+|!x*r ~K;xj100788
Ch N$t9m1007884 /North America/Canada/Ontario/TorontoITPUB个人空间#{%ka7c @?,ftS6{5K~r
ITPUB个人空间T-d"Q4F}3S KCb
2 /North America/USAITPUB个人空间.G6q?T$` p
ITPUB个人空间hDm5H/R3x
3 /North America/USA/CaliforniaITPUB个人空间oiK(}-xL2iOh%XV
ITPUB个人空间AC.i9N2i)uOH;fW
4 /North America/USA/California/Redwood Shores
   在 Oracle 10g 中,还有其他更多关于层次查询的新特性 。例如,有的时候用户更关心的是每个层次分支中等级最低的内容。那么你就可以利用伪列函数CONNECT_BY_ISLEAF来判断当前行是不是叶子。如 果是叶子就会在伪列中显示“1”,如果不是叶子而是一个分支(例如当前内容是其他行的父亲)就显示“0”。下给出了一个关于这个函数使用的例子:
select connect_by_isleaf,sys_connect_by_path(child,'/') path
w7x}VbV1Oh4|(Mu100788
1zZ P(?E+\ \|x{6Xk100788from hierITPUB个人空间 ny"Rw L1YQ
ITPUB个人空间,kjQi&Kk1Gp&{F
start with parent is nullITPUB个人空间'e7Gq?G!uDglY2D

aC'F#y no v4[100788connect by prior child = parent;
v(e a%zl,E100788ITPUB个人空间7O%r/bB$l@[
CONNECT_BY_ISLEAF PATHITPUB个人空间/R`;EWN

f7b$r s5g&i100788----------------------------------
0 /Asia
zg!]w0c]100788ITPUB个人空间k-dna&Xc*n
0 /Asia/China
0tSS$E)@.|&eV-W100788ITPUB个人空间^(ki7uO ufQp7X
1 /Asia/China/BeijingITPUB个人空间5z | ti+i0}no
ITPUB个人空间;r*mAMT0dJ
0 /Asia/Japan
xv|el/z1wB7u100788ITPUB个人空间Mcr%T~K ~^9j
1 /Asia/Japan/OsakaITPUB个人空间&X2y)k(U R%S

&F,\1R$@f:d ~2D4n"T1007881 /Asia/Japan/TokyoITPUB个人空间j.Ty(W3w"]/R l
ITPUB个人空间1QQ.|H!K u!d\)wD
0 /AustraliaITPUB个人空间D3EW%N~U'q3f
ITPUB个人空间 ~sWqF y1B6l:j
0 /Australia/New South Wales
{m?.y}R-n!t100788
KX7hKP#Z1007881 /Australia/New South Wales/SydneyITPUB个人空间e u'j4y Z(M Fi;A
ITPUB个人空间'M5u,N;E@Hy
0 /EuropeITPUB个人空间g(i\QY)Qq

V0n MtD w X1007880 /Europe/United KingdomITPUB个人空间suMh2F r UF
ITPUB个人空间6s`0A @C*v
0 /Europe/United Kingdom/EnglandITPUB个人空间k b4j*F^)G8rx
ITPUB个人空间+M&R!L!khj-r9hOi7R
1 /Europe/United Kingdom/England/London
}3}DQ7xNvJ100788ITPUB个人空间8h)e(S&iK
0 /North AmericaITPUB个人空间'A {\)?zMU
ITPUB个人空间jvL;q*~IU#}
0 /North America/Canada
p Al1P/[KK0qzV100788
LhF3I@3{)q1007880 /North America/Canada/Ontario
5E I6XM_e|!~100788
g f$TL3z2r!D1007881 /North America/Canada/Ontario/Ottawa
&h1]UG:?]100788
'N)^l;t.A5T8I*J+eOX-Q+D1007881 /North America/Canada/Ontario/Toronto
^V ^b'qM100788ITPUB个人空间3L l:k+V;KO's[
0 /North America/USAITPUB个人空间p-LH({%| _ Yo2i-?
ITPUB个人空间/G,@&EZl _
0 /North America/USA/California
/|cH]_p.u100788ITPUB个人空间(V)m Z1d5A%xR
1 /North America/USA/California/Redwood Shores
  自从Since Oracle 9i 开始,就可以通过 SYS_CONNECT_BY_PATH 函数实现将从父节点到当前行内容以“path”或者层次元素列表的形式显示出来。 如下例所示:
column path format a50ITPUB个人空间Rf6}t1i(E9l

:o Rfj!gf-Ct ?Ao100788select level,sys_connect_by_path(child,'/') path
E~/p `?~_ `100788
9l%Zxe6A+_100788from hier
$BU-]Az#d100788
f-e7\l9wKs4P100788start with parent is null
zS t5M4e~Pbc100788
0[ nvx:y0hf q oy Q100788connect by prior child = parent;
Oy"C'`Z9L100788
et\s4S _100788LEVEL PATH ITPUB个人空间g;o.H(]fH

Hdt Z)Jd100788-------- --------------------------------------------ITPUB个人空间jV8?l8EutMJ

3I v(y ]lO9G1007881 /AsiaITPUB个人空间"`;Nwn"h};^5c l ``
ITPUB个人空间8w6A#@n[9Jzm
2 /Asia/China
:F:a6Da [a4d:X;c*E100788ITPUB个人空间LB h_7@0o+a
3 /Asia/China/Beijing
6laze-Ac.]:X&?+~!WcQ100788ITPUB个人空间-I IRa;[Z
2 /Asia/Japan
4P3UcC-Od7x100788
_ I$mC/tpp1007883 /Asia/Japan/OsakaITPUB个人空间#} iw\:?
ITPUB个人空间pbrc]I h0B
3 /Asia/Japan/Tokyo
` X4G\G7qY100788ITPUB个人空间3h$cp-?)WK9U
1 /AustraliaITPUB个人空间*Vxz?KH8Q&x

%^oJ yd7L1007882 /Australia/New South WalesITPUB个人空间-|}8d[%g,}_4?5A2EP

W{"j8N.D.e:CO1007883 /Australia/New South Wales/SydneyITPUB个人空间.Tf yPDB{

7^ L#UDp(L)t1007881 /EuropeITPUB个人空间I5HJ n&hq/c4x"^?#Iv*F

2p4] l;[G&K ^1007882 /Europe/United Kingdom
}{x|.LI.e100788
5[Q,l/q T5l']#t1007883 /Europe/United Kingdom/EnglandITPUB个人空间,j5X j4k'Wph
ITPUB个人空间+jH:G"T@iQ
4 /Europe/United Kingdom/England/LondonITPUB个人空间-U8Ox4TOeL

o+m"zxuz8e H1007881 /North AmericaITPUB个人空间9JEUR@3i6SE

^p k*}s_!J} jpx1007882 /North America/CanadaITPUB个人空间#ItMZ`*k

%D"m%Qj} y1007883 /North America/Canada/OntarioITPUB个人空间.X(q Ce'Qw/j
ITPUB个人空间7^*s~Q#m
4 /North America/Canada/Ontario/Ottawa
9tH ]x8IgFQ100788ITPUB个人空间[ HqxO5z
4 /North America/Canada/Ontario/TorontoITPUB个人空间$lPF(p5W X3E`.L

']s{(E"pA1007882 /North America/USAITPUB个人空间1AH2_4o2uTmO3I
ITPUB个人空间A)Vo;\cL.W.o
3 /North America/USA/CaliforniaITPUB个人空间6qQ`;gQ-K

(q P ?d)E&Xo/N1007884 /North America/USA/California/Redwood Shores

  在 Oracle 10g 中,还有其他更多关于层次查询的新特性 。例如,有的时候用户更关心的是每个层次分支中等级最低的内容。那么你就可以利用伪列函数CONNECT_BY_ISLEAF来判断当前行是不是叶子。如 果是叶子就会在伪列中显示“1”,如果不是叶子而是一个分支(例如当前内容是其他行的父亲)就显示“0”。下给出了一个关于这个函数使用的例子:

select connect_by_isleaf,sys_connect_by_path(child,'/') path
Yo%h"TK100788
5^ rW4NtE5Hu100788from hier
/R3Zz}!LDv j100788
_\0],{$Z+H/j100788start with parent is nullITPUB个人空间o4y%Z,Dv)V{ F
ITPUB个人空间2t6G+c%_9S&w

TAG:

 

评分:0

我来说两句

显示全部

:loveliness: :handshake :victory: :funk: :time: :kiss: :call: :hug: :lol :'( :Q :L ;P :$ :P :o :@ :D :( :)

Open Toolbar