在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 |
|
|
|
|
|