2010-11-24 38 views
2

我有一個t-sql查詢的問題。T-SQL如何從T-SQL中的樹中獲取所有項目?

比方說,我有一個分類樹(分類ID)

cat_table

1 
| 
2-\ 
| 3-\ 
6 | 5 
| 4 | 
... ... 

ads_table

ad_ID 
category_ID 
當然

cat_table

IDcategory_ID列引用

問題是,如何獲得(遞歸?)來自所有類別的所有廣告,其中最頂端的父類是第一類?

回答

1

您是否熟悉SQL Server中的公用表表達式? CTE的許多用途之一是執行遞歸查詢。

以下是我關於這個問題找到了最好的文章之一:

http://www.4guysfromrolla.com/webtech/071906-1.shtml

+0

文章鏈接說:無法顯示頁面,因爲發生內部服務器錯誤。 – 2014-09-24 20:08:41

+0

[answer]「鼓勵與外部資源的鏈接,但請在鏈接中添加上下文,以便您的同行用戶瞭解它是什麼以及爲什麼在那裏。始終引用重要鏈接中最相關的部分,以防目標網站無法訪問或永久離線。「 – AndyJ 2017-04-25 09:05:16

9

嘗試使用遞歸公用表表達式,又名 「CTE」(可在SQL Server 2005及以上)是這樣的:

--go through a nested table supervisor - user table and display the chain 
DECLARE @Contacts table (id varchar(6), first_name varchar(10), reports_to_id varchar(6)) 
INSERT @Contacts VALUES ('1','Jerome', NULL) -- tree is as follows: 
INSERT @Contacts VALUES ('2','Joe' ,'1')  --      1-Jerome 
INSERT @Contacts VALUES ('3','Paul' ,'2')  --     /  \ 
INSERT @Contacts VALUES ('4','Jack' ,'3')  --    2-Joe   9-Bill 
INSERT @Contacts VALUES ('5','Daniel','3')  --   /  \    \ 
INSERT @Contacts VALUES ('6','David' ,'2')  --  3-Paul   6-David  10-Sam 
INSERT @Contacts VALUES ('7','Ian' ,'6')  -- / \   / \ 
INSERT @Contacts VALUES ('8','Helen' ,'6')  -- 4-Jack 5-Daniel 7-Ian 8-Helen 
INSERT @Contacts VALUES ('9','Bill ' ,'1')  -- 
INSERT @Contacts VALUES ('10','Sam' ,'9')  -- 

DECLARE @Root_id char(4) 

--get 2 and below 
SET @Root_id=2 
PRINT '@Root_id='+COALESCE(''''[email protected]_id+'''','null') 
;WITH StaffTree AS 
(
    SELECT 
     c.id, c.first_name, c.reports_to_id, c.reports_to_id as Manager_id, cc.first_name AS Manager_first_name, 1 AS LevelOf 
     FROM @Contacts     c 
      LEFT OUTER JOIN @Contacts cc ON c.reports_to_id=cc.id 
     WHERE [email protected]_id OR (@Root_id IS NULL AND c.reports_to_id IS NULL) 
    UNION ALL 
     SELECT 
      s.id, s.first_name, s.reports_to_id, t.id, t.first_name, t.LevelOf+1 
     FROM StaffTree   t 
      INNER JOIN @Contacts s ON t.id=s.reports_to_id 
    WHERE [email protected]_id OR @Root_id IS NULL OR t.LevelOf>1 
) 
SELECT * FROM StaffTree 

輸出:

@Root_id='2 ' 
id  first_name reports_to_id Manager_id Manager_first_name LevelOf 
------ ---------- ------------- ---------- ------------------ ----------- 
2  Joe  1    1   Jerome    1 
3  Paul  2    2   Joe    2 
6  David  2    2   Joe    2 
7  Ian  6    6   David    3 
8  Helen  6    6   David    3 
4  Jack  3    3   Paul    3 
5  Daniel  3    3   Paul    3 

(7 row(s) affected) 

變化@Root_id得到不同輸出:

@Root_id=null 
id  first_name reports_to_id Manager_id Manager_first_name LevelOf 
------ ---------- ------------- ---------- ------------------ ----------- 
1  Jerome  NULL   NULL  NULL    1 
2  Joe  1    1   Jerome    2 
9  Bill  1    1   Jerome    2 
10  Sam  9    9   Bill    3 
3  Paul  2    2   Joe    3 
6  David  2    2   Joe    3 
7  Ian  6    6   David    4 
8  Helen  6    6   David    4 
4  Jack  3    3   Paul    4 
5  Daniel  3    3   Paul    4 

(10 row(s) affected) 
2

還有就是要避免樹瀏覽查詢復發的一個選項。您可以將「路徑」列添加到您的類別樹中。它應該包含用某些非數字字符(如斜槓)分隔的每個元素祖先ID。

例如您的「ID = 4」類別的路徑看起來就像是:「/ 1/2/3 /」 現在,當您加入廣告表類別你需要做以下幾點:

select * from ads_table 
inner join cat_table on cat_table.ID = ads_table.category_ID 
where cat_table.Path like '/1/%' 

這就是你的查詢。

你可以閱讀更多關於這個話題我blog post