回答

收藏

SQL Server 2008 CTE递归

技术问答 技术问答 389 人阅读 | 0 人回复 | 2023-09-14

我正在尝试执行我认为使用CTE进行递归比较困难的事情是SQL Server 2008。
2 [0 {5 _5 u0 W/ e! @  m. M在下面的示例中,您可以假设固定深度为3 …没有任何比这更低的深度了。在现实生活中,深度是“更深的”,但仍然是固定的。在示例中,我尝试将其简化一些。
* d! m* {* |) p8 M7 @7 g我的输入数据如下。. o) I* {) T2 \( Z4 y& ^4 f
ID     PARENT_ID       NAME          DEPTH! y# }1 G% z; J# K6 n
------------------------------------------0 C! [. v  X: ?- J
1      NULL            A             1
9 Y( u# o' Y" u2      1               B             2
2 }, w1 o9 V: P" d) y0 J/ k3      2               C             3; Q0 G4 T/ y1 f
4      1               D             2
0 v: p% o5 Y6 e9 `我的CTE的输出应为下表。
) x' Q- H% F; eLEVEL1_ID    LEVEL2_ID    LEVEL3_ID    LEVEL1_NAME    LEVEL2_NAME    LEVEL3_NAME
, L/ X6 y' i2 b--------------------------------------------------------------------------------% o& @0 I, e( y5 g
1            NULL         NULL         A              NULL           NULL2 [5 }+ C+ }* n& G# I+ g2 W3 |
1            2            NULL         A              B              NULL
* X& ]0 ]. S, u$ I3 E1            2            3            A              B              C, v/ W. N4 u2 v, y& A+ I
1            4            NULL         A              D              NULL5 w" y" l7 g' @* S
如果我可以在输出中获得ID列,则可以肯定地可以映射到查找表中的名称。
  w- j2 R% `% w' Q+ G我也乐于接受其他方法来完成此任务,包括使用SSIS。
4 q  F+ `; X4 }4 x1 O- N6 m               
- A& I1 ?8 N; I3 ^* k0 n$ Q解决方案:
2 g' I0 N$ p. W( H; a% j( b- A  z                  z3 n( E& y: `$ r- u* |

7 @/ \! a/ Z+ w; e) x- l8 S. L; x; O  \! k
                并不是真的那么难做:/ }9 \$ |0 m( o2 K- M. H
;WITH cte AS
& T2 g. p( C5 `/ {) q" J$ H(( {/ T5 S% D9 ?' n' B, T# p
    SELECT CAST('/' + Name AS VARCHAR(50)) as 'CteName', ID
& X0 a9 U2 K% e7 q* t    FROM dbo.YourTable
3 |/ G8 t* ^" X  v    WHERE parent_id IS NULL
" V1 M  v! h1 c3 B: X% E; H) ]" e* o    UNION ALL( Q$ P9 P" j3 Q3 |: e8 d6 ^
    SELECT CAST(cte.CteName + '/' + Name AS VARCHAR(50)), t.ID
' T/ Q$ Y, ^) D& w1 F    FROM dbo.YourTable t6 u6 x2 d$ `6 x$ k
    INNER JOIN cte ON t.parent_id = cte.id
9 |1 V8 O5 J9 f9 X)
$ a" B1 V; ~$ w) tSELECT cteName FROM cte
  _; j, t/ O9 g/ a6 y9 a& HORDER BY ID8 p7 H4 [& w4 |
给我输出:
/ \) m6 s! a" j" ?: w" l- J: S+ g9 u* d/A
- O: G1 M8 H) S( D7 N/A/B- U% |+ E/ Q2 m( {9 Y$ O) W
/A/B/C  M# S. D6 K' P7 v* o
/A/D% h3 e3 [! P- y( l$ g
附带说明:“深度”可以由CTE轻松计算,您不必将其存储在表中(请参阅Level我添加的列):& r0 i- d3 ^6 m* k: B1 D
;WITH cte AS
6 U: K2 @0 u; G  K0 V& v; ~(6 @* b; g, `9 o/ w/ Q
    SELECT , A- Y) A' J5 l( q, Y
       CAST('/' + Name AS VARCHAR(50)) as 'CteName', ID, - f4 b2 F! H, a# p' h- s6 y
       1 AS 'Level'
; P/ d# {4 m* K8 k- W% ~5 y6 _    FROM dbo.YourTable# ~) d2 n: p5 f. Y: I2 ~; S
    WHERE parent_id IS NULL' t( ?. M6 g& ^- v, a
    UNION ALL5 v4 v7 `' y; G
    SELECT
/ \6 L9 q, |8 E3 f5 S3 P: V% |       CAST(cte.CteName + '/' + Name AS VARCHAR(50)), t.ID,
7 g+ [5 I+ P3 R' a8 g       cte.Level + 1 AS 'Level'4 A. M/ B: k# n6 A2 _
    FROM dbo.YourTable t
8 C9 k% f7 Z- }/ N9 f' Q" _$ s9 Z    INNER JOIN cte ON t.parent_id = cte.id
: i' B. B- m# w- f& c% R9 @1 y! S0 Z)
5 |/ H% z; D! H! Y# g0 g) pSELECT cteName FROM cte& _; i) E, q1 G" _: n+ P
ORDER BY Level, ID
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则