回答

收藏

在SQL Server中查找顶级父级的最有效方法?

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

给出下表6 C5 c9 O" `- A; X
catName     catID     parentID6 a5 F5 @) W- T6 [0 j  h5 c! B
=================================+ _! _# \  w1 e6 [
vehicles    1         0- k/ G8 d0 l% D) d5 i/ ]  {$ ^9 ^
cars        2         14 e5 g$ E9 x5 ?/ [. }
sedans      3         2. X- Z9 N4 p& }' |* `8 e
animals     4         0/ j( l: d( L& a# B6 B& U
cows        5         45 d( K" ?8 U* O' ?* X" ?+ c& I, v
给定一个catID,我需要找到其顶级父级(parentID = 0)。
  n- [- _' P9 z. G) _每天执行50-100次此查询。当前有100-200行(将来可能会更多)。多达8个层次的深度。我在考虑三种选择:2 _8 n# ^" _" s$ F% r+ K& E
[ol]使用递归方法
% i" ?& {& I1 H5 Z& v# A. r8 D/ U创建一个视图" b( }: R2 L  J+ e; U$ _
添加另一列topParentID(最不满意)) i4 [0 X9 {: Z7 Y/ X3 J8 B  g
[/ol]1 O+ |  ?- w2 K: D  R
哪个效率最高?
7 m1 }4 P4 y$ T' g8 F                . G/ K$ E8 ^, ]
解决方案:2 s, O% e  }/ V4 i# T
                ! ?8 R! t: s$ L& K0 j  G  c' L
: n- E- @4 ?, b  s  S9 h
5 |/ M, Z' k8 J5 w3 I2 R0 t
                SQL2008 +:' g7 x1 ^% o; j: s$ j9 L
为了存储层次结构,SQL Server包含HIERARCHYID数据类型。可以将上述数据“转换为”以使用HIERARCHYID“值”:
2 T$ [8 x# H3 b/ s# |( ^' DcatName     catID     parentID  hierarchyNode# e' Y  t& X8 j& B
=============================================, H+ ?- g, K9 ^3 C5 M
vehicles    1         0         /1/9 B+ n3 M5 `) r
cars        2         1         /1/2/  S. @8 ~+ C; M
sedans      3         2         /1/2/3/
; E& x/ P; ~' E) U- f) ianimals     4         0         /4/
5 ?& A; j7 t. w  E; G6 ecows        5         4         /4/5/
) g3 G# O$ s5 T/ n转换后,我将删除parentID列。* D7 L; x7 `8 V
HIERARCHYID是SQLCLR系统数据类型,其中包括以下方法:
8 L4 |" U: `: b" J0 N0 n+ F7 jHidValue。GetLevel()
2 x, f: W& d" H8 E; bHidValue。GetAncestor(level)。: [& G( W5 S: p1 o

1 P" C1 T) W' @3 u为了获得父节点,我将使用以下方法:
0 _$ o- Y/ `/ f4 ?, jDECLARE @node HIERARCHYID
$ G# d7 i, G! B# J: s: |! w+ Z6 n) XSET     @node = '/1/2/3/': n6 B) d/ h3 b6 j6 e
SELECT  
0 J* }7 @' b6 V+ g: N    currentNodeLvl= @node.GetLevel(),                                 --> 3
0 F4 K, N+ M6 J    parentAsHID   = @node.GetAncestor(@node.GetLevel() - 1),          --> 0x58$ a* t7 C! Z: I3 a
    parentAsString= @node.GetAncestor(@node.GetLevel() - 1).ToString()--> /1/$ R9 _4 ?/ J. {
此外,我将在hierarchyNode列上创建索引,因此:" @: H( J$ ]' U
CREATE UNIQUE INDEX IUN_Table_hierarchyNode1 o- E4 ~& A) W% o3 l' m
ON dbo.Table(hierarchyNode)9 T7 d: q- N5 Q
最后的查询将是:9 M7 ^3 @1 L4 s2 B. B
SELECT ..., prt.catID AS parentID, r6 T: a4 s# M; [9 A& @9 F1 p3 p7 |
FROM dbo.Table crt -- Curent node2 E/ s$ P" O3 z
LEFT/INNER JOIN -- It depends on hierarchyID nullability ' U) b% q8 u& v% D. e8 x4 r
dbo.MyTable prt -- Parent node3 x6 O8 j" r, V. k- }; |( m* `$ h
ON @node.GetAncestor(crt.hierarchyID.GetLevel() - 1).ToString() = prt.hierarchyID
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则