回答

收藏

计算分层SQL数据中的子代数

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

对于一个简单的数据结构,例如:/ M1 _+ C2 V  K: e  R/ ]0 ^
ID    parentID    Text        Price6 ]: |9 u; s4 l" L, g7 R4 N
1                 Root
, E$ b! g/ N+ I" s+ K2     1           Flowers4 o9 _, ^- B% H0 ]& p+ E4 T1 \
3     1           Electro
  [. s/ y5 v( ^1 a, @$ k& E% w3 |4     2           Rose        10
/ t0 l8 A+ Z# J; v* \% [& O5 P5     2           Violet      5
% s8 ], I$ z. N" d* _4 x& z6     4           Red Rose    12
9 m, h9 ]8 D+ L" p7     3           Television  100- [$ E0 ^9 H  E" L/ A* S7 H, C/ t
8     3           Radio       70! b' L4 ?+ m- w9 |4 N5 z0 X
9     8           Webradio    90
* o5 b2 E( J. A; L1 A: L供参考,层次树如下所示:
' L& V! \$ }0 }) `: xID    Text        Price7 ]2 C3 ]& W9 Z% G* D  K( i
1     Root0 I  n+ J" y" @) n9 G) s0 S0 I
|2    Flowers
7 \& N& N$ u% q. g|-4   Rose        10
/ P1 s0 F6 o/ G* X" d| |-6 Red Rose    12
9 s, \6 Y5 W, N+ X9 E|-5   Violet      5. G  p0 Y. I8 c; I0 |7 N
|3    Electro7 i! M; p$ g  `6 g8 r" z7 Z
|-7   Television  100
  K( E0 H; F; ]+ j6 K- m5 Z|-8   Radio       70
3 h7 {$ Y5 B0 Q  |-9 Webradio    90
' I$ b, S7 M9 q; G' D  t0 ~3 N我想计算每个级别的孩子人数。因此,我将获得一个新列“ NoOfChildren”,如下所示:! u, E: @) O8 }2 Z
ID    parentID    Text        Price  NoOfChildren
; Z; s- d* M- K+ |0 U; a3 G1                 Root               86 M4 q1 `) {% ]& m6 t, L  m
2     1           Flowers            3+ @# p; Q( \: k5 G5 x' N
3     1           Electro            3( k# ~; q7 {) x8 ^+ w( d
4     2           Rose        10     1
0 r2 x% G) |4 O  A6 v; m2 I1 B5     2           Violet      5      0
( [" ]/ z7 F! g: o) K- G6     4           Red Rose    12     0: Z$ H: q: [# ^- w, }
7     3           Television  100    0. v' I; N4 T* @
8     3           Radio       70     1
# h8 J3 F6 K* P1 V% R& J" O9     8           Webradio    90     0: e1 ]8 _. ^5 B0 a% X2 j9 `1 _1 @
我读了一些有关分层数据的内容,但是我不知何故卡在了parentID的多个内部联接上。也许有人可以在这里帮助我。
+ p: ~4 @0 ~  M                7 X6 U8 \4 M/ d& Q
解决方案:' e2 \# z% n% j3 F% k5 w/ M
               
1 W5 K7 T1 s$ s6 E0 q1 ^# }3 o, M$ S2 H! [. _( s- @

6 f  L3 \" I% U7 L/ h  ^                使用 CTE可以满足您的需求。& H+ J/ B& D7 T( |  l  X
递归地遍历所有孩子,记住根。
0 [3 S7 Q1 u1 O; QCOUNT 每个根的项目。
' ~' ]( w- \- [JOIN 这些再次与您的原始表一起产生结果。
4 B0 q$ W1 b# o5 w

! H0 O3 ?2 ?  @" A" H, k, d( h测试数据8 O9 o9 I! m2 E  u
DECLARE @Data TABLE (
& L7 x) R( n0 S! }. s  ID INTEGER PRIMARY KEY
7 m) w9 q# A" S& o, a8 K- ]  , ParentID INTEGER
# [9 B, g' _" e, M0 v3 G# {, p  , Text VARCHAR(32)  d% ~0 U7 `  E. R4 `4 t; A# F
  , Price INTEGER
  t8 B3 G+ A8 e5 |4 })
5 M% _# x, ^8 H: S6 r, B$ |INSERT INTO @Data7 F9 F5 `( V$ T
  SELECT 1, Null, 'Root', NULL4 E" J( v4 [% F4 ~3 \
  UNION ALL SELECT 2, 1, 'Flowers', NULL* \$ w  W" a9 t, K. s3 O
  UNION ALL SELECT 3, 1, 'Electro', NULL
: o- f1 p% V' Y3 d3 R; r  UNION ALL SELECT 4, 2, 'Rose', 10  t3 W" S( L- w* G9 C
  UNION ALL SELECT 5, 2, 'Violet', 5( j" H* H. l  }# x! f4 x1 R* `
  UNION ALL SELECT 6, 4, 'Red Rose', 12
' a  y# s- ], y% a( g. J  UNION ALL SELECT 7, 3, 'Television', 100/ x9 |+ [5 G" Z
  UNION ALL SELECT 8, 3, 'Radio', 705 h8 g1 G4 n0 U2 S
  UNION ALL SELECT 9, 8, 'Webradio', 90
5 |0 q+ T( V3 M, J, h0 J" G' XSQL语句
, [+ V2 ^3 [& C  A. R;WITH ChildrenCTE AS (, h' Z) t9 x2 J) S
  SELECT  RootID = ID, ID7 u0 n' g- j4 Z! N9 o. m
  FROM    @Data6 L$ e% U& D- v! M
  UNION ALL% D( A& |. f* d# [- e- ^' }
  SELECT  cte.RootID, d.ID
6 b0 g! i3 S2 M! O4 L' a8 ~  FROM    ChildrenCTE cte1 W) F3 E8 [5 [& {9 u/ [5 L' }5 B
          INNER JOIN @Data d ON d.ParentID = cte.ID
/ {! d' x- @% U% S)
0 M% E9 o- i8 \+ t/ |% VSELECT  d.ID, d.ParentID, d.Text, d.Price, cnt.Children
4 |) s: E6 b2 ]% e" p+ KFROM    @Data d- x% m  H" T$ |  d+ e4 v
        INNER JOIN (
/ h* N+ c+ F  t) z) {; Z3 v          SELECT  ID = RootID, Children = COUNT(*) - 1/ w' o3 z6 z: \' L* T+ {
          FROM    ChildrenCTE3 i, _6 g2 V. q+ ^4 H
          GROUP BY RootID
" Q5 R% S; O4 V  v$ F        ) cnt ON cnt.ID = d.ID
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则