如果當前查詢效果很好,你爲什麼要改變呢?
您應該首先考慮是否需要遞歸獲取數據。然後,如果您確實需要遞歸過程,則CTE可能是一種選擇,而不是其他方式:意思是說,無論您是否需要遞歸數據,您都希望實現遞歸CTE。
遞歸CTE可以使用很多資源,它只能在需要時使用,它是最好的選擇。
下面有一對夫婦遞歸CTE,帶有示例emplyee和manager表。
當您想通過管理員和員工表的層次遞歸瀏覽時,可以使用遞歸CTE。
如果你wan't知道誰是工作的人這樣一個上帝之下,在層次結構的任何級別,就可以使用這樣的CTE:
Declare @data table(id int, name varchar(10), manager int)
insert into @data(id, name, manager) values
(0, 'God', null)
, (1, 'John', 0)
, (2, 'Bob', 1)
, (3, 'Lisa', 0)
, (4, 'Jorg', 1)
, (5, 'Mike', 3)
, (6, 'Nick', 5);
with cte(level, id) as (
Select 0, id From @data Where manager in (Select id From @data Where name = 'God')
Union All
Select level+1, d.id From @data d
Inner Join cte c on c.id = d.manager
)
Select c.level, d.name, manager = m.name
From cte c
Inner Join @data d on d.id = c.id
Inner Join @data m on d.manager = m.id
Order by level
輸出:
level name manager
0 John God
0 Lisa God
1 Mike Lisa
1 Bob John
1 Jorg John
2 Nick Mike
這裏的水平表示在name
和God
之間有N個管理員。
如果你wan't計算有多少員工正在努力爲每一位員工,你可以使用遞歸CTE像這樣的:
with cte(level, id, manager) as (
Select 0, id, id From @data
Union All
Select level+1, c.id, d.id From @data d
Inner Join cte c on c.manager = d.manager
)
Select d.name, employees = count(*)-1
From cte c
Inner Join @data d on d.id = c.id
Group By d.name
OPTION(MAXRECURSION 0)
輸出:
name employees
Bob 0
God 6
John 2
Jorg 0
Lisa 2
Mike 1
Nick 0
這是一種很難說什麼時候你不解釋你想要達到的目標。 – JodyT
@JodyT道歉。我有兩個表:A)mail_list_id,它有兩列,都有ID,特別是在經理 - 員工關係中(每個經理ID都有多個僱主ID)。表B是具有所有用戶詳細信息的用戶表(如員工表)。目標是獲得兩列:經理姓名和員工姓名。我基本上想要mail_list_id表,而不是id我想要的名字。希望這可以清除事情。 – Crabster
通常,如果您對管理員有不平衡的員工層次結構,那麼您會在此處使用遞歸CTE。例如,如果您的員工與經理直接鏈接,並與另一位與小組負責人有聯繫的員工聯繫,小組負責人又與經理建立了聯繫。您將使用遞歸CTE來回溯「上游鏈」,直到找到實際經理,即將與員工/經理的關係變平。看起來你的數據不適合這一點,因爲每個員工都已經與他們的經理有直接的聯繫。 –