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

标签 sql sql-server

给出下表

catName     catID     parentID
=================================
vehicles    1         0
cars        2         1
sedans      3         2
animals     4         0
cows        5         4

给定一个 catID,我需要找到它的顶级父级 (parentID = 0)。

此查询每天执行 50-100 次。目前有 100-200 行(将来可能更多)。深达 8 层。我在考虑三种选择:

  1. 使用递归方法
  2. 创建 View
  3. 添加另一列topParentID(最不受欢迎)

哪个最有效?

最佳答案

SQL2008+:

为了存储层次结构,SQL Server 包括 HIERARCHYID数据类型。以上数据可以“转换”为使用 HIERARCHYID “值”,因此:

catName     catID     parentID  hierarchyNode
=============================================
vehicles    1         0         /1/
cars        2         1         /1/2/
sedans      3         2         /1/2/3/
animals     4         0         /4/
cows        5         4         /4/5/

转换后,我将删除 parentID 列。

HIERARCHYID 是 SQLCLR 系统数据类型,包括以下 methods :

为了获得父节点,我会使用这些方法:

DECLARE @node HIERARCHYID
SET     @node = '/1/2/3/'

SELECT  
    currentNodeLvl= @node.GetLevel(),                                 --> 3
    parentAsHID   = @node.GetAncestor(@node.GetLevel() - 1),          --> 0x58
    parentAsString= @node.GetAncestor(@node.GetLevel() - 1).ToString()--> /1/

此外,我会在 hierarchyNode 列上创建一个索引,因此:

CREATE UNIQUE INDEX IUN_Table_hierarchyNode
ON dbo.Table(hierarchyNode)

最终查询将是:

SELECT ..., prt.catID AS parentID
FROM dbo.Table crt -- Curent node
LEFT/INNER JOIN -- It depends on hierarchyID nullability 
dbo.MyTable prt -- Parent node
ON @node.GetAncestor(crt.hierarchyID.GetLevel() - 1).ToString() = prt.hierarchyID

关于sql - 在 SQL Server 中查找顶级父级的最有效方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28777426/

相关文章:

mysql - 如何使用随机事件名称从存储过程创建事件?

sql - 如何在 Amazon Redshift 中选择多个填充常量的行?

sql - 有没有办法在 SQL 播种脚本中获取 Visual Studio 环境变量?

java - 如何从 jOOQ 中的值 T 明确创建 Field<T> ?

java - SQL 数据库和 Java

sql-server - 在 INSTEAD OF INSERT 触发器的 OUTPUT 子句中,是否可以引用两个 INSERTED 表?

sql - 将整个 SQL Server 数据库提取到 CSV 文件

c# - 同一 SPROC 的每次迭代执行时间变慢

sql-server - 如果 T-SQL 中不存在特定参数,则阻止执行查询

python - 如何解决使用可信连接连接到 MS Sql Server 的 Mac OS 上的票证过期错误