dual的一些巧妙用法

2021-07-07 05:45:01 字數 3890 閱讀 5358

dual

是乙個只有一條記錄的表

select * from dual

dummy

x1,生成序列

select level from dual  connect by level <= 3;   /   select rownum from dual  connect by rownum <= 3;

select level from dual  connect by  1=1;

2,配合to_date函式生成乙個從2015-1-1開始的日期序列

select level,(to_date('20150101', 'yyyy-mm-dd') + level - 1) cur_date from dual            

connect by level <= sysdate - to_date('20150101', 'yyyy-mm-dd') + 1

3,   with  x  as  

( select  'aa'  chr  from  dual

union  all  

select  'bb'  chr  from  dual)

select  level ,chr,lpad( ' ' ,( level - 1 )* 5 , '-' )||chr other  from  x  connect  by  level <= 3

level chr    other

1     aa     aa

2     aa     ---- aa

3     aa     --------- aa

3     bb     --------- bb

2     bb     ---- bb

3     aa     --------- aa

3     bb     --------- bb

1     bb     bb

2     aa     ---- aa

3     aa     --------- aa

3     bb     --------- bb

2     bb     ---- bb

3     aa     --------- aa

3     bb     --------- bb        

可見是全部level的樹形結構,當掃瞄物件是dual時,即乙個level只生成一條記錄.   

aaa表有3行資料:a,b,c

level

偽列表示樹的深度(或叫高度)

下圖為select id,level from aaa connect by level<4時遞迴查詢到的樹狀結構:

由上圖,可以得出規律如下:

n+n的二次方+。。。。。+n的level次方

其中,n表示表中有n條記錄,level表示上述樹狀圖中的樹的層數,也就是指connect by 子句中的level偽列(或是rownum偽列)值。

樹每增加一層,則n+n的二次方+。。。。。+n的level+1次方=n+n*(

n+n的二次方+。。。。。+n的level次方)。

於是可以總結出

f(n,l)=∑power(n,p), p取值為[1,l),即level=1時,power(3,1)=3  level=2時,power(3,2)=9,即12-3,level=3時,power(3,3)=27,即39-12。

從而得出如下結論:

假設表中有n條記錄,則記f(n,l)為select id,level from t connect by level

注釋:

當連線條件(connect by

條件)沒有限制記錄之間的關係(即connect by裡沒有類似 id=prior  pid的條件,而是connect by rownumconnect by level)時,每一條記錄都會作為自己或者其他記錄的子節點,也就說,每一條記錄的子節點就是表上所有的記錄。而樹的層數就是rownum(或是level)值。

這就是oracle採用了深度優先的演算法。

僅當from後面的表只有一行(比如dual)時,level和rownum可以互換。

with t as (select level l from dual connect by level<=3)

select rownum,l,level from t connect by level<=2

---- 總共兩層資料,第二層是 t 的自身笛卡爾積,3+3*3 = 12 行

rownum          l      level

---------- ---------- ----------

1          1          1

2          1          2

3          2          2

4          3          2

5          2          1

6          1          2

7          2          2

8          3          2

9          3          1

10          1          2

11          2          2

12          3          2

12 rows selected.

with t as (select level l from dual connect by level<=3)

select rownum,l,level from t connect by rownum=2

---- 總共兩層資料,第二層受制於connect by條件,只有一行

rownum          l      level

---------- ---------- ----------

1          1          1

2          1          2  ------rownum的生成順序是深度優先,第二層第一條得到rownum=2,在這裡停止

3          2          1  ------第一層資料不受connect by制約,全部輸出。

4          3          1

另一問題類似。

對於有n條記錄的來說,如果沒有遞迴條件,直接connect by level,先深度搜尋,再廣度,則每個節點作為根節點,然後自身和其他節點為子節點,然後下個子節點還包括自身和其他節點,然後同樣迭代。所以,總共記錄數有n*2^0+n*2^1+.........    其中0,1....為level

則記f(n,l)為 select id,level from t connect by level

f(n,l) = f(n,l-1)*n+n

於是可以總結出

f(n,l)=∑power(n,p), p取值為[1,l)

總記錄數n,level層數p

結果集數:t=∑n^x(x=1...p)

比如,總記錄數為3,層數為3

則結果集數:3^1 +3^2 + 3^3 = 3+9+27=39

connect by rownum及connect by level

MyBatis 的4個巧妙用法

由於mybatis的對映檔案遵循xml檔案的格式,所以不能使用像大於號或者小於號這樣的xml檔案特殊字元,需要使用轉義字元代替。小於號 大於號 和 單引號 雙引號 可以使用 select from test where 1 1 and start date current date and end ...

oracle中dual的一些學習了解

進了專案組才正式接觸oracle,以前的都是用的mysql,先前以為dual表是資料庫中的開發人員建立的普通表,當時還傻乎乎的去找,後來才查詢實質了解是怎麼回事,下面是一些參考和總結。dual是乙個虛擬表,用來構成select的語法規則,oracle保證dual裡面永遠只有一條記錄,可以用它來做很多...

的一些用法

action標籤,顧名思義,是用來呼叫action的標籤,在jsp中頁面中,可以具體指定某一命名空間中的某一action。而標籤的主體用於顯示及渲染actionr的處理結果。action標籤有如下幾個屬性 id 可選屬性,作為該action的引用id name 必選屬性,指定呼叫action nam...