【问题标题】:How to turn this cursor operation into a set based operation on a closure hierarchy?如何将此游标操作转换为基于闭包层次结构的集合操作?
【发布时间】:2019-05-26 19:51:26
【问题描述】:
  1. Trees.DirectReports 是一个闭包(层次结构)表。
  2. 有一个名为Users 的表:RowID, EmployeeId, and MangerId@RowCount 是该表中的记录数,#EmpMgr 是该表的游标。

以下是我想将基于游标的操作转换为基于集合的操作的相关 sql 代码。

WHILE @RowCount <= @NumberRecords --loop through each record in Users table
BEGIN       
    SET @EmpId = (SELECT EmployeeId FROM #EmpMgr WHERE RowID = @RowCount)
    SET @MgrId = (SELECT ManagerId FROM #EmpMgr WHERE RowID = @RowCount)

    INSERT INTO [Trees].[DirectReports](EmployeeId, ManagerId, Depth)
    SELECT c.EmployeeId, p.ManagerId, p.Depth + c.Depth + 1
    FROM Trees.DirectReports p join Trees.DirectReports c
    WHERE p.EmployeeId = @MgrId AND c.ManagerId = @EmpId

    SET @RowCount = @RowCount + 1
END

所以我真的很想弄清楚如何将其作为一个集合查询来执行,因为我知道这样会更快,但我的大脑今天还没有建立正确的连接来解决这个问题。

*请注意,要回答这个问题,您需要已经了解闭包表的工作原理。否则上面的内容可能没有意义。

【问题讨论】:

    标签: sql sql-server-2012 hierarchy hierarchical-data transitive-closure-table


    【解决方案1】:

    在其他几篇文章的帮助下找到了我正在寻找的东西。主要答案是这样的:

    WITH cte AS
    (
        SELECT LegacyId ancestor, LegacyId descendant, 0 depth FROM Users
        UNION ALL
    
        SELECT cte.ancestor, u.LegacyId descendant, cte.depth + 1 depth
        FROM   dbo.Users u JOIN cte ON u.ManagerId = cte.descendant
    )
    select * from cte
    

    然而,起初让我失望的是,有一些不良数据导致了循环依赖。我能够使用以下查询来确定这些实例的位置:

    with cte (id,pid,list,is_cycle) 
    as
    (
        select      legacyid id, managerid pid,',' + cast (legacyid as varchar(max))  + ',',0
        from        users
    
        union all
    
        select      u.legacyid id, 
                    u.managerid pid, 
                    cte.list + cast(u.legacyid as varchar(10)) +  ',' ,case when cte.list like '%,' + cast (u.legacyid as varchar(10)) + ',%' then 1 else 0 end
        from        cte join users u on u.managerid = cte.id
        where       cte.is_cycle = 0
    )
    select      *
    from        cte
    where       is_cycle = 1
    

    一旦我纠正了周期性数据,一切都很好。查看以下 SO 帖子以获取更多信息,因为这些是我曾经提出的解决方案:Is there a way to detect a cycle in Hierarchical Queries in SQL Server?How can I create a closure table using data from an adjacency list?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-10-05
      • 2016-06-08
      • 2012-07-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多