回答

收藏

SQL Server 2008 CTE递归

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

我正在尝试执行我认为使用CTE进行递归比较困难的事情是SQL Server 2008。
' D+ ?8 e! N$ i% I# I4 C在下面的示例中,您可以假设固定深度为3 …没有任何比这更低的深度了。在现实生活中,深度是“更深的”,但仍然是固定的。在示例中,我尝试将其简化一些。8 I7 k! C$ g2 q0 E, q. t! M! d
我的输入数据如下。
8 j( P1 _2 M) ?+ o2 m6 K; J" J# R, JID     PARENT_ID       NAME          DEPTH1 G7 X( a9 e( N+ H/ w
------------------------------------------
2 p% L1 W9 Y% ?; t1      NULL            A             1
: w7 }/ I+ v6 m: H+ r1 L2      1               B             2  g2 Y7 j: h1 s) J, Z
3      2               C             3
8 E3 E% b7 U1 g( q2 |1 A4      1               D             2. N2 w0 R) `2 @' Q/ s/ t
我的CTE的输出应为下表。, B! r' ]& U7 B. r) U$ a; Q4 u- r
LEVEL1_ID    LEVEL2_ID    LEVEL3_ID    LEVEL1_NAME    LEVEL2_NAME    LEVEL3_NAME
' T, \4 E( q" G- d! \9 ^--------------------------------------------------------------------------------* J0 ^9 o; \+ [8 E
1            NULL         NULL         A              NULL           NULL
" V& i1 {- \. [1 m2 M1            2            NULL         A              B              NULL- P1 s1 `$ g1 p9 m5 Q& q
1            2            3            A              B              C
+ i8 o: l6 o& N1            4            NULL         A              D              NULL2 h! J& V0 U: {+ H9 f
如果我可以在输出中获得ID列,则可以肯定地可以映射到查找表中的名称。& B9 R: k3 u. d: ]
我也乐于接受其他方法来完成此任务,包括使用SSIS。4 I- v* u  a1 R1 P- f
               
! i  L! y2 c' E: i解决方案:! w) j8 n6 x" e5 y$ i( K
               
% `0 b* A) P( C. E2 T7 ~  H- z% a3 I/ n: h* _& H* g  I
6 J- O1 M- C3 S' w
                并不是真的那么难做:
- ]) u' k1 z2 f+ D;WITH cte AS
8 D1 ]0 o1 b$ W(3 X) r8 A6 r% A, e! s9 \
    SELECT CAST('/' + Name AS VARCHAR(50)) as 'CteName', ID
5 y  e( Q9 y. u    FROM dbo.YourTable7 m8 J% s; p4 Q& i' Y1 M) v5 R4 N
    WHERE parent_id IS NULL
) o3 r" p1 j1 G! {( r    UNION ALL0 I8 H2 J( l- x& y4 Z
    SELECT CAST(cte.CteName + '/' + Name AS VARCHAR(50)), t.ID* \8 d! Z( |; K
    FROM dbo.YourTable t
: g/ Q0 r* ~3 z' k& [' J    INNER JOIN cte ON t.parent_id = cte.id
" ~( M  Y( Q2 z: G)/ X# ?# }' M" i. m
SELECT cteName FROM cte
' L5 h# e! y4 n# |ORDER BY ID8 j0 \: d2 t2 N, T9 ?( p5 `: d
给我输出:
9 v! X) G, g% f; u' Z2 {5 k/A, e! S) |9 Y1 F) I0 Q4 P, m3 c* W
/A/B
4 a7 w! C7 K* c0 @( _4 O3 V/A/B/C
! z3 `" [1 h- W0 M$ B/A/D$ J1 J  `8 B8 U/ \7 x
附带说明:“深度”可以由CTE轻松计算,您不必将其存储在表中(请参阅Level我添加的列):; P' m4 s$ [7 B% s
;WITH cte AS- k) a, L3 D. R( o4 F
(. R2 I( Y& F5 Y, t$ `; U
    SELECT
8 h' x4 s" B$ ?9 P/ X9 l7 R) A$ [       CAST('/' + Name AS VARCHAR(50)) as 'CteName', ID, $ s8 ?2 T3 A$ M! c% b' t" w
       1 AS 'Level'2 B( V  G6 N2 y, s! R/ C1 M! V
    FROM dbo.YourTable
, c- c; @) D0 l, n  c    WHERE parent_id IS NULL4 n9 C. k* d( w$ ~% u
    UNION ALL+ s3 ?# D  b7 ?3 L6 ?
    SELECT
' b; f9 e0 m! }1 m5 w       CAST(cte.CteName + '/' + Name AS VARCHAR(50)), t.ID,6 p1 D% `7 Y1 T" O. Y
       cte.Level + 1 AS 'Level'
/ k" F9 z* I! ^. k    FROM dbo.YourTable t
& }/ o2 p; E4 X+ v    INNER JOIN cte ON t.parent_id = cte.id% m  z% x5 E1 V* q/ S
)$ G# l8 ?" p- \, G2 Y: ]
SELECT cteName FROM cte
4 g# Z7 F& J. fORDER BY Level, ID
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则