【问题标题】:SYS_CONNECT_BY_PATH equivalent in t-SQLt-SQL 中的 SYS_CONNECT_BY_PATH 等效项
【发布时间】:2021-05-13 16:31:31
【问题描述】:

我需要将我的 Oracle 查询转换为 SQL Server。

查询会根据用户名生成一个“管理层级”。输出将有一个管理链,其中最后一个元素是当前管理器。

表:

EE_USERNAME     MGR_USERNAME  
user1       ceo
user2       user1
user3       user2
user4       user1
user5       user2
user6       user3

样本输出:

user1: ceo
user2: ceo,user1
user3: ceo,user1,user2
user4: ceo,user1
user5: ceo,user1,user2
user6: ceo,user1,user2,user3

我的 Oracle 查询:

SELECT EMPLOYEE_DATA.* ,  SYS_CONNECT_BY_PATH(MGR_USERNAME, ',') "Path"
FROM EMPLOYEE_DATA
START WITH MGR_USERNAME = 'ceo'
CONNECT BY NOCYCLE  prior  EE_USERNAME = MGR_USERNAME   

此查询的 SQL Server 等效项是什么?

【问题讨论】:

  • 您可能想要研究递归 CTE。

标签: sql sql-server tsql common-table-expression recursive-query


【解决方案1】:

Charlieface 的查询省略了 Oracle 的 NOCYCLE 指令提供的功能,该指令表示如果同一记录再次返回,则停止递归。

如果您想要这种保护,您可以在 CTE 查询的递归部分添加 Where 子句:

Where Instr(mgr.EE_Username,mgr.Path)=0

【讨论】:

    【解决方案2】:
    ;WITH cte AS (
        SELECT e.*, mgr.EE_USERNAME AS Path
            FROM EMPLOYEE_DATA AS mgr
            JOIN EMPLOYEE_DATA AS e ON mgr.EE_USERNAME = e.MGR_USERNAME
            WHERE mgr.EE_USERNAME = 'ceo'
        UNION ALL
        SELECT e.*, mgr.Path + ',' + mgr.EE_USERNAME AS Path
            FROM cte AS mgr
            JOIN EMPLOYEE_DATA e ON mgr.EE_USERNAME = e.MGR_USERNAME
    )
    SELECT *
    FROM cte
    -- OPTION (MAXRECURSION 200)  -- if you need a different value
    ;
    

    如果你做了很多递归,你应该看看MAXRECURSION,它的默认值为 100。

    【讨论】:

    • 谢谢你,这行得通!是不是预计查询处理时间会比Oracle慢很多?
    • 我是 Stack Overflow 的新手。我找不到接受答案并关闭线程的选项,你能指导我吗?谢谢!
    • 左侧的复选标记。可能相同的性能,即好但不是很好,应该避免这些类型的查询。它在后台使用了一个非常快的临时表,但是对于大量数据或大量递归,它可能会很慢。不要忘记查找OPTION (MAXRECURSION...
    猜你喜欢
    • 2017-10-07
    • 1970-01-01
    • 2016-08-19
    • 2012-08-23
    • 1970-01-01
    • 2012-10-09
    • 1970-01-01
    • 2020-05-09
    • 2015-06-28
    相关资源
    最近更新 更多