參考網路上CTE範例
資料表Employee內容如下
EmpNum EmpName Job SNum
A01 老總 總經理 0
B23 陳一哥 經理 A01
B666 蘇老大 組長 B23
C666 燈芸姊 全端工程師 B666
C52 大搖哥 全能工程師 B666
經CTE遞回跑出來的階層(JobLevel)如下
EmpNum EmpName Job SNum JobLevel
A01 老總 總經理 0 1
B23 陳一哥 經理 A01 2
B666 蘇老大 組長 B23 3
C666 燈芸姊 全端工程師 B666 4
C52 大搖哥 全能工程師 B666 4
CTE語法如下
WITH EmployeeOrder AS (
--找出老大
SELECT EmpNum, EmpName
, Job
, SNum
, 1 AS JobLevel
FROM #Employee WHERE SNum = '0'
UNION ALL
SELECT A.EmpNum, A.EmpName
, A.Job, A.SNum
, (B.JobLevel + 1) AS JobLevel --職位等級+1
FROM #Employee A
INNER JOIN EmployeeOrder B ON A.SNum = B.EmpNum
)
SELECT * FROM EmployeeOrder
第一步初始條件 EmployeeOrder的結果
EmpNum EmpName Job SNum JobLevel
A01 老總 總經理 0 1
遞迴第一次 EmployeeOrder的結果
EmpNum EmpName Job SNum JobLevel
A01 老總 總經理 0 1
B23 陳一哥 經理 A01 2
遞迴第二次,Employee INNER JOIN EmployeeOrder,感覺應該是類似作下面這個動作
SELECT A.EmpNum, A.EmpName, A.Job, A.SNum
FROM Employee A
INNER JOIN ( SELECT EmpNum FROM #Employee WHERE EmpNum IN ('A01', 'B23') ) B
ON A.SNum = B.EmpNum
會得到
EmpNum EmpName Job SNum
B23 陳一哥 經理 A01
B666 蘇老大 組長 B23
再跟原本的EmployeeOrder做UNION ALL的話,陳一哥的資料不是應該會出現二次嗎?
但為何最後的結果不會重複?
遞迴執行的語意如下:
查詢語法
WITH EmployeeOrder AS (
--找出老大
SELECT EmpNum, EmpName
, Job
, SNum
, 1 AS JobLevel
FROM #Employee WHERE SNum = '0'
UNION ALL
SELECT A.EmpNum, A.EmpName
, A.Job, A.SNum
, (B.JobLevel + 1) AS JobLevel --職位等級+1
FROM #Employee A
INNER JOIN EmployeeOrder B ON A.SNum = B.EmpNum
)
SELECT * FROM EmployeeOrder
依照上面描述查詢結果集順序如下
錨點結果集
A01 老總 總經理 0 1
第一次結果集 因為 A.SNum = B.EmpNum
,B = A01
連結 A
表 所以得到
B23 陳一哥 經理 A01 2
第二次結果集 B = B23
連結 A
表 所以得到
B666 蘇老大 組長 B23 3
第三次結果集 B = B666
連結 A
表 所以得到
C666 燈芸姊 全端工程師 B666 4
C52 大搖哥 全能工程師 B666 4
所以將所有結果集 T(0) + T(1) + T(2) + T(3) 可得到
A01 老總 總經理 0 1
B23 陳一哥 經理 A01 2
B666 蘇老大 組長 B23 3
C666 燈芸姊 全端工程師 B666 4
C52 大搖哥 全能工程師 B666 4
我之前有分享 CTE RECURSIVE (遞迴)製作月曆 有簡單介紹原理