成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

詳解SQL Server 2008中CTE遞歸查詢的實現

數據庫 SQL Server
說到SQL Server 2008中的CTE查詢,主要是對查詢樹形或層次結構的數據很有用。這里將為大家詳細介紹如何實現它。

今天基本搞清楚SQL Server中遞歸查詢的實現方式,So,先記錄下來。不過呢,個人覺得SQL Server的遞歸查詢相對于Oracle中的遞歸查詢更加難以理解。

從SQL Server 2005開始,我們可以直接通過CTE來支持遞歸查詢,這對查詢樹形或層次結構的數據很有用。CTE即公用表表達式,雖然不恰當,但你可以將它看做成一個臨時命名的結果集合。

我們先建立一個示例表,名稱為MENU,表示菜單的層次結構:

  1. CREATE TABLE MENU   
  2.  (  
  3.     name nvarchar(50) NOT NULL PRIMARY KEY,  
  4.     senior nvarchar(50) NULL 
  5. );  
  6.    
  7.  INSERT INTO MENU values 
  8.     ('文件',NULL),  
  9.     ('新建','文件'),  
  10.     ('項目','新建'),  
  11.     ('使用當前連接查詢','新建'); 

表示的菜單層次如下:

  1. 文件   
  2.     新建   
  3.         項目   
  4.         使用當前連接查詢  
  5.  
  6. OK,先看CTE的語法:   
  7.   WITH CTE名稱(字段列表)   
  8.   AS   
  9.   (   
  10.     查詢語句   
  11.   ) 

 

例如:

  1. WITH lmenu(name,senior)   
  2. as   
  3. (   
  4.     SELECT name,senior from menu   

我們定義了一個名稱為lmenu的CTE,這樣我們后續即可直接使用lmenu來查詢,如:

  1. SELECT * FROM lmenu 

如果我們在定義CTE的查詢語句中直接引用CTE表本身,則會形成遞歸查詢,當然遞歸查詢具有自己的特殊結構,下面的SQL通過遞歸查詢獲取每個菜單的層次深度:

  1. WITH lmenu(name,senior,levelas 
  2.  (  
  3.     SELECT NAME,SENIOR,0 level FROM MENU WHERE SENIOR IS NULL 
  4.     UNION ALL 
  5.     SELECT A.NAME,A.SENIOR,b.level+1 FROM MENU A,lmenu b  
  6.     where a.senior = b.name 
  7. )  
  8.  
  9. SELECT *  from lmenu 

結果:

 

  1. name               senior              level   
  2. ----------------------------------- -----------   
  3. 文件                NULL                 0   
  4. 新建                文件                  1   
  5. 使用當前連接查詢      新建                 2   
  6. 項目                新建                 2 

注意查詢定義語句,它由兩條查詢語句構成,其中

  1. SELECT NAME,SENIOR,0 level FROM MENU WHERE SENIOR IS NULL 

稱為定位成員,SQL Server通過此語句來判斷是否繼續進行遞歸。

  1. SELECT A.NAME,A.SENIOR,b.level+1 FROM MENU A,lmenu b   
  2.     where a.senior = b.name 

稱之為遞歸成員,其特征為from子句中引用了CTE對象自身。

遞歸CTE具有一些限制條件(引自MSDN):

至少有一個定位點成員和一個遞歸成員,當然,你可以定義多個定位點成員和遞歸成員,但所有定位點成員必須在遞歸成員的前面

定位點成員之間必須使用UNION ALL、UNION、INTERSECT、EXCEPT集合運算符,最后一個定位點成員與遞歸成員之間必須使用UNION ALL,遞歸成員之間也必須使用UNION ALL連接

定位點成員和遞歸成員中的字段數量和類型必須完全一致

遞歸成員的FROM子句只能引用一次CTE對象

遞歸成員中不允許出現下列項 

  1. SELECT DISTINCT   
  2. GROUP BY   
  3. HAVING   
  4. 標量聚合   
  5. TOP   
  6. LEFTRIGHTOUTER JOIN(允許出現 INNER JOIN)   
  7. 子查詢 

CTE遞歸查詢的執行方式:

遞歸的終止依賴于定位點成員的,如果理解了這一點,也就理解了遞歸查詢的執行方式。

我們來看上例的執行執行過程:

  1. SELECT * FROM lmenu 

這條語句進入遞歸查詢

  1. SELECT A.NAME,A.SENIOR,b.level+1 FROM MENU A,lmenu b   
  2.     where a.senior = b.name 

作為最外層的語句,顯然遞歸的第一層應該根據MENU表的記錄來循環(如果查詢執行計劃,這表示一個嵌套循環),假設menu表中查詢出的記錄順序如下:

  1. name                                       senior   
  2. --- --------------------------------------------------   
  3. 文件                                          NULL   
  4. 新建                                            文件   
  5. 使用當前連接查詢                       新建   
  6. 項目                                            新建 

第一條記錄:

首先判斷是否進入遞歸,由于 文件包含在定位點成員結果集中,不符合遞歸條件,所以不進入遞歸,直接返回從定位點成員集合中返回記錄:

  1. select name,senior,0 level from menu where senior is null and name='文件' 

 

  1. name                    senior           level   
  2. --------------- ------------------------ -----------   
  3. 文件                      NULL                0 

第二條記錄:

即NAME = '新建', 定位點成員結果集中沒有該記錄,將進入遞歸:

將當前行的值帶入遞歸成員:

  1. SELECT A.NAME,A.SENIOR,b.level+1 level FROM MENU A,lmenu b   
  2.     where a.senior = b.name   
  3.         AND a.senior = '文件'   
  4.         AND a.name='新建' 

由于遞歸的關聯條件是a.senior = b.name,所以b.name='文件',以此條件進入下級遞歸,這實際上就是第一條記錄的情況,由于name='文件'符合定位點條件,所以將終止遞歸,如果我們用子查詢來替換掉lmenu遞歸成員,第二條記錄的查詢語句實際為:

  1. SELECT a.name,a.senior,b.level+1 from menu a, (  
  2.   select name,senior,0 level  from menu 
  3. where senior is null and name='文件' 
  4. ) b  
  5. where a.senior=b.name 
  6.     and a.senior = '文件' 
  7.     and a.name='新建' 

name            senior                    level
--------------------- --------------------------
新建             文件                           1

第三條記錄:

NAME='使用當前連接查詢',同樣不符合定位點條件,將進入遞歸:

  1. SELECT A.NAME,A.SENIOR,b.level+1 FROM MENU A,lmenu b   
  2.     where a.senior = b.name   
  3.           AND a.senior = '新建'   
  4.           AND a.name = '使用當前連接查詢' 

同樣,代入當前記錄條件,下級遞歸b.name='新建',由于'新建'還不符合定位點條件,所以還將繼續遞歸,及lmenu b表示子查詢:

  1. select c.name,c.senior,d.level+1 level from menu c,lmenu d   
  2. where c.senior = d.name   
  3.      and c.name = '新建'   
  4.      and c.senior = '文件' 

替換成上述語句后,d.name='文件',將再次判斷是否需要繼續遞歸,由于'文件'符合終止遞歸條件,所以將終止遞歸。

我們用子查詢表示第三條記錄的遞歸過程如下:

  1. SELECT a.name,a.senior,b.level+1 level FROM menu A,(  
  2.         select c.name,c.senior,d.level+1 level from menu c,(  
  3.           select name,senior,0 level from menu where senior is null and name='文件' 
  4.     ) d  
  5.     where c.senior = d.name 
  6.         and c.name = '新建' 
  7.         and c.senior = '文件'     
  8. ) b  
  9. where a.senior = b.name 
  10.     and a.senior = '新建' 
  11.     and a.name = '使用當前連接查詢' 

name                                     senior                    level

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

使用當前連接查詢                    新建                       2

第四條記錄與第三條記錄的遞歸層次完全一樣。

原文標題:SQL Server 2008中的CTE遞歸查詢

鏈接:http://www.cnblogs.com/xfrog/archive/2010/10/10/1847462.html

【編輯推薦】

  1. SQL Server 2000刪除實戰演習
  2. SQL Server存儲過程的命名標準如何進行?
  3. 卸載SQL Server 2005組件的正確順序
  4. 對SQL Server字符串數據類型的具體描述
  5. SQL Server數據類型的種類與應用

 

責任編輯:彭凡 來源: 博客園
相關推薦

2011-08-19 14:38:22

SQL Server 2008遞歸查詢

2009-03-17 13:25:13

查詢遷移SQL Server

2010-10-14 09:32:52

SQL Server

2011-08-19 10:40:27

SQL Server Merge命令

2021-04-25 09:42:40

SQL遞歸SQL Server

2011-08-19 11:00:54

SQL Server WaitFor命令

2023-08-29 09:46:12

SQLCTE遞歸

2011-08-19 11:26:41

SQL Server 主密鑰

2011-03-15 10:22:42

SQL Server 聯機事務處理

2009-04-16 18:15:19

動作審核審核活動SQL Server

2009-04-16 17:44:31

2011-09-01 15:24:22

SQL Server 存儲過程調試

2009-04-27 14:48:44

2011-09-01 18:38:02

SQL Server 文件流功能

2011-08-01 10:09:57

SSAS數據庫

2010-08-26 10:45:33

死鎖SQL Server

2010-05-13 10:00:10

SQL Server

2013-05-08 10:01:55

SQL Server 數據備份備份與還原

2022-03-15 08:36:46

遞歸查詢SQL

2011-08-19 11:10:54

SQL Server DBCC OPENTR會話查詢事務
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产三区视频在线观看 | 日韩精品免费 | 国产精品国产三级国产aⅴ无密码 | 国产欧美在线 | 国产乱码久久久久久一区二区 | 欧美成人精品一区二区三区 | 九九热免费视频在线观看 | 久久久久久久久久久久久91 | 国产成人精品一区二 | 亚洲免费精品 | 久久这里只有精品首页 | 久久婷婷香蕉热狠狠综合 | 中文字幕精品一区 | 国产精品福利一区二区三区 | 91秦先生艺校小琴 | 亚洲乱码一区二区三区在线观看 | 欧美在线a | 欧美日韩免费在线 | 亚洲视频欧美视频 | 色男人天堂av| 一区二区av | 99精品国产一区二区三区 | 国产精品久久久久影院色老大 | 国产成人高清 | 91精品国产综合久久婷婷香蕉 | 视频一区二区中文字幕 | 久久久精品网 | 亚洲成人www | 在线中文字幕第一页 | 日韩一区二区av | 欧美黄色网络 | 久久久.com | 成人免费在线 | 一区二区免费 | 久久久久久久国产 | 国产精品免费一区二区三区 | 黄色片在线 | 国产精品日韩在线观看一区二区 | 日韩激情在线 | 天天干夜夜操视频 | 国产精品久久久久一区二区三区 |