国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
Oracle的Connect By理解

connect by中的條件就表示了父子之間的連接關(guān)系 比如 connect by id=prior pid,但如果connect by中的條件沒有表示記錄之間的父子關(guān)系那會出現(xiàn)什么情況?

常見的,connect by會在構(gòu)造序列的時候使用

select rownum from dual connect by rownum<xxx

代替早期版本的

select rownum from all_objects where rownum <xxx

我們注意到,dual是一個只有一條記錄的表,如果表有多條記錄,將會怎樣?

下面開始實驗

CREATE TABLE T(ID VARCHAR2(1 BYTE));INSERT INTO T ( ID ) VALUES ( 'A'); INSERT INTO T ( ID ) VALUES ( 'B'); INSERT INTO T ( ID ) VALUES ( 'C'); COMMIT;SQL> select id,level from t connect by level<2;I LEVEL- ----------A 1B 1C 1SQL> select id,level from t connect by level<3;I LEVEL- ----------A 1A 2B 2C 2B 1A 2B 2C 2C 1A 2B 2C 2已選擇12行。SQL> select id,level from t connect by level<4;I LEVEL- ----------A 1A 2A 3B 3C 3B 2A 3B 3C 3C 2A 3B 3C 3B 1A 2A 3B 3C 3B 2A 3B 3C 3C 2A 3B 3C 3C 1A 2A 3B 3C 3B 2A 3B 3C 3C 2A 3B 3C 3已選擇39行。

我們很快可以找到其中的規(guī)律,假設(shè)表中有N條記錄, 則記F(N,l)為select id,level from t connect by level<l 的結(jié)果集數(shù)目

那么,

F(N,1)=N

F(N,l) = F(N,l-1)*N+N

于是可以總結(jié)出

F(N,l)=∑power(N,p), p取值為[1,l)

要解釋,也很容易: 當連接條件不能限制記錄之間的關(guān)系時每一條記錄都可以作為自己或者其他記錄的葉子

如下所示:

A          1

A          2

A          3

B          3

C          3

B          2

A          3

B          3

C          3

C          2

A          3

B          3

在這里,我們看到的是Oracle采用了深度優(yōu)先的算法

我們接著看一個例子,看看在SQL中通過connect by如何將任意一個整數(shù)(不要太大就行)拆分為若干個power(2,n)的和的方法。

先構(gòu)造測試數(shù)據(jù):

create table ba(n number);insert into ba select 5*rownum from dual connect by rownum<5;commit;select * from ba;
N
-------
5
10
15
20

一個得出結(jié)果的簡單的SQL為

  1. select distinct a.n , level, bitand(a.n,power(2,level-1)) from ba a connect by level<=floor(log(2,n)+1)

這里為什么要加distinct?你可以嘗試去掉distinct ,看看結(jié)果與保持distinct有多大差別。

然后我們先來看,如果只對其中的一條記錄進行操作,那么加不加distinct,結(jié)果是否是一樣的?比如我們只看第一條記錄5的拆分結(jié)果

select distinct a.n , level, bitand(a.n,power(2,level-1)) from (select * from ba where rownum=1) a connect by level<=floor(log(2,n)+1);

結(jié)果為:

  1. N    LEVEL    BITAND(A.N,POWER(2,LEVEL-1))
  2. ----------------------------------------------------------------
  3. 5    1             1
  4. 5    2             0
  5. 5    3             4

去掉distinct的sql為

  1. select a.n , level, bitand(a.n,power(2,level-1)) from (select * from ba where rownum=1) a connect by level<=floor(log(2,n)+1);

輸出結(jié)果,自己運行一下看看。然后你就該思考了,為什么你看到的結(jié)果會是這樣???

這里不做過多解釋,做完上面的實驗,然后結(jié)合1樓中所說的,我想你應該就能明白了。

事實上我們有更好的辦法來處理:

with a as (select n, floor(log(2,n)+1) lc from ba)select a.n, bitand(a.n,power(2,b.rn-1)) from a, (select rownum rn from	(select max(lc) mlc from a) 	connect by level<=mlc)bwhere rn<=a.lcorder by 1,2

內(nèi)層SQL先取得所有記錄中可拆分出來的power(2,n)中的n最大可能是多少,然后由此構(gòu)造出序列,最后再做一次關(guān)聯(lián)查詢,

用限制條件rn<=a.lc限制住每個N中可拆分出來的power(2,n)中的n的最大值,由此可以高效得出結(jié)果。

上例實質(zhì)上與 對多記錄按各自指定次數(shù)重復 的性質(zhì)是一樣的。

簡單總結(jié):

對單記錄/單條數(shù)據(jù)使用connect by,沒問題

但對多條記錄使用connect by,就會碰到問題,千萬要注意。

elect rownum,       level,       sys_connect_by_path(id, ',') path,       id,       connect_by_isleaf isleaf  from tconnect by nocycle level < 2order by rownum, level, path;select rownum,       level,       sys_connect_by_path(id, ',') path,       id,       connect_by_isleaf isleaf  from tconnect by nocycle level < 3order by rownum, level, path;select rownum,       level,       sys_connect_by_path(id, ',') path,       id,       connect_by_isleaf isleaf  from tconnect by nocycle level < 4order by rownum, level, path;下面是執(zhí)行結(jié)果:CHENCH@orcl> select rownum,  2	 level,  3	 sys_connect_by_path(id, ',') path,  4	 id,  5	 connect_by_isleaf isleaf  6    from t  7  connect by nocycle level < 2  8   order by rownum, level, path;    ROWNUM      LEVEL PATH       ID     ISLEAF---------- ---------- ---------- -- ----------	 1	  1 ,A	 A	   1	 2	  1 ,B	 B	   1	 3	  1 ,C	 C	   1Elapsed: 00:00:00.01CHENCH@orcl>CHENCH@orcl> select rownum,  2	 level,  3	 sys_connect_by_path(id, ',') path,  4	 id,  5	 connect_by_isleaf isleaf  6    from t  7  connect by nocycle level < 3  8   order by rownum, level, path;    ROWNUM      LEVEL PATH       ID     ISLEAF---------- ---------- ---------- -- ----------	 1	  1 ,A	 A	   0	 2	  2 ,A,A       A	   1	 3	  2 ,A,B       B	   1	 4	  2 ,A,C       C	   1	 5	  1 ,B	 B	   0	 6	  2 ,B,A       A	   1	 7	  2 ,B,B       B	   1	 8	  2 ,B,C       C	   1	 9	  1 ,C	 C	   0	10	  2 ,C,A       A	   1	11	  2 ,C,B       B	   1    ROWNUM      LEVEL PATH       ID     ISLEAF---------- ---------- ---------- -- ----------	12	  2 ,C,C       C	   112 rows selected.Elapsed: 00:00:00.01CHENCH@orcl>CHENCH@orcl> select rownum,  2	 level,  3	 sys_connect_by_path(id, ',') path,  4	 id,  5	 connect_by_isleaf isleaf  6    from t  7  connect by nocycle level < 4  8   order by rownum, level, path;    ROWNUM      LEVEL PATH       ID     ISLEAF---------- ---------- ---------- -- ----------	 1	  1 ,A	 A	   0	 2	  2 ,A,A       A	   0	 3	  3 ,A,A,A     A	   1	 4	  3 ,A,A,B     B	   1	 5	  3 ,A,A,C     C	   1	 6	  2 ,A,B       B	   0	 7	  3 ,A,B,A     A	   1	 8	  3 ,A,B,B     B	   1	 9	  3 ,A,B,C     C	   1	10	  2 ,A,C       C	   0	11	  3 ,A,C,A     A	   1    ROWNUM      LEVEL PATH       ID     ISLEAF---------- ---------- ---------- -- ----------	12	  3 ,A,C,B     B	   1	13	  3 ,A,C,C     C	   1	14	  1 ,B	 B	   0	15	  2 ,B,A       A	   0	16	  3 ,B,A,A     A	   1	17	  3 ,B,A,B     B	   1	18	  3 ,B,A,C     C	   1	19	  2 ,B,B       B	   0	20	  3 ,B,B,A     A	   1	21	  3 ,B,B,B     B	   1	22	  3 ,B,B,C     C	   1    ROWNUM      LEVEL PATH       ID     ISLEAF---------- ---------- ---------- -- ----------	23	  2 ,B,C       C	   0	24	  3 ,B,C,A     A	   1	25	  3 ,B,C,B     B	   1	26	  3 ,B,C,C     C	   1	27	  1 ,C	 C	   0	28	  2 ,C,A       A	   0	29	  3 ,C,A,A     A	   1	30	  3 ,C,A,B     B	   1	31	  3 ,C,A,C     C	   1	32	  2 ,C,B       B	   0	33	  3 ,C,B,A     A	   1    ROWNUM      LEVEL PATH       ID     ISLEAF---------- ---------- ---------- -- ----------	34	  3 ,C,B,B     B	   1	35	  3 ,C,B,C     C	   1	36	  2 ,C,C       C	   0	37	  3 ,C,C,A     A	   1	38	  3 ,C,C,B     B	   1	39	  3 ,C,C,C     C	   139 rows selected.Elapsed: 00:00:00.04
關(guān)鍵是 connect by 后面不管是level 還是 rownum都是在查詢結(jié)果集內(nèi)作的限制

SQL> with t as ( 2 select 1 from dual 3 union all 4 select 2 from dual 5 union all 6 select 3 from dual) 7 select * from t connect by rownum < 5; 1---------- 1 1 1 1 2 3已選擇6行。SQL> with t as (select 1 from dual) 2 select * from t connect by rownum < 5; 1---------- 1 1 1 1已選擇4行。
with a as (	select 5 as n from dual	union all	select 10 from dual	union all	select 15 from dual	union all	select 20 from dual	)select  distinct a.n , level, bitand(a.n,power(2,level-1)) from a connect by level<=floor(log(2,n)+1);SQL> with a as (  2	  select 5 as n from dual  3	  union all  4	  select 10 from dual  5	  union all  6	  select 15 from dual  7	  union all  8	  select 20 from dual  9	 ) 10  select  distinct a.n , level, bitand(a.n,power(2,level-1)) from a connect by level<=floor(log(2,n)+1);		 N	  LEVEL BITAND(A.N,POWER(2,LEVEL-1))---------- ---------- ----------------------------		10		  4							8		15		  2							2		20		  2							0		20		  4							0		15		  3							4		 5		  1							1		10		  3							0		10		  1							0		20		  3							4		 5		  2							0		20		  5						   16		10		  2							2		 5		  3							4		15		  4							8		15		  1							1		20		  1							0已選擇16行。
SQL> with a as (  2          select 5 as n from dual  3          union all  4          select 10 from dual  5          union all  6          select 15 from dual  7          union all  8          select 20 from dual  9         ) 10     select  distinct a.n , level, bitand(a.n,power(2,level-1)) from (select * from a where rownum=1) a connect by level<=floor(log(2,n)+1);         N      LEVEL BITAND(A.N,POWER(2,LEVEL-1))---------- ---------- ----------------------------         5          1                            1         5          2                            0         5          3                            4已選擇3行。SQL> with a as (  2          select 5 as n from dual  3          union all  4          select 10 from dual  5          union all  6          select 15 from dual  7          union all  8          select 20 from dual  9         ) 10     select  a.n , level, bitand(a.n,power(2,level-1)) from (select * from a where rownum=1) a connect by level<=floor(log(2,n)+1);         N      LEVEL BITAND(A.N,POWER(2,LEVEL-1))---------- ---------- ----------------------------         5          1                            1         5          2                            0         5          3                            4已選擇3行。
SQL>    with a as (  2          select 5 as n from dual  3          union all  4          select 10 from dual  5          union all  6          select 15 from dual  7          union all  8          select 20 from dual  9         ) 10     select * from a where a.n=5 connect by rownum<6;         N----------         5         5         5         5         5
SQL>    with a as (  2          select 5 as n from dual  3          union all  4          select 10 from dual  5          union all  6          select 15 from dual  7          union all  8          select 20 from dual  9         ) 10     select * from a where rownum=1 connect by rownum<6;ERROR:ORA-30009: CONNECT BY 操作內(nèi)存不足
with a as (	select 5 as n from dual	union all	select 10 from dual	union all	select 15 from dual	union all	select 20 from dual     ) select * from a where a.n=5 connect by level<6;
5555555555已選擇341行。
本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊舉報
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
一個比較難的SQL(Oracle 9i 實現(xiàn) 10G 的 CONNECT_BY_ISLEA...
Oracle中遞歸查詢(START WITH……CONNECT BY……)
圣誕快樂: 用 GaussDB T 繪制一顆圣誕樹,兼論高斯數(shù)據(jù)庫語法兼容
Connect By、Level、Start With的使用
Oracle遞歸查詢(start with…connect by prior)
orcal 時間分組查詢
更多類似文章 >>
生活服務(wù)
分享 收藏 導長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服