Sql server Oracle SYS\u CONNECT\u BY\u路径等效查询到SQL Server

Sql server Oracle SYS\u CONNECT\u BY\u路径等效查询到SQL Server,sql-server,tsql,hierarchical-data,recursive-query,Sql Server,Tsql,Hierarchical Data,Recursive Query,我正在尝试将涉及Oracle SYS_CONNECT_BY_PATH语法的复杂查询转换为SQL Server: SELECT DISTINCT TO_CHAR(CONCAT(@ROOT, SYS_CONNECT_BY_PATH(CONCAT('C_',X), '.'))) AS X_ALIAS , TO_CHAR(CONCAT(@ROOT, PRIOR SYS_CONNECT_BY_PATH(CONCAT('C_',X), '.')

我正在尝试将涉及Oracle SYS_CONNECT_BY_PATH语法的复杂查询转换为SQL Server:

    SELECT 
           DISTINCT TO_CHAR(CONCAT(@ROOT, SYS_CONNECT_BY_PATH(CONCAT('C_',X), '.'))) AS X_ALIAS
                , TO_CHAR(CONCAT(@ROOT, PRIOR SYS_CONNECT_BY_PATH(CONCAT('C_',X), '.'))) AS X_ALIAS_FATHER
                , TO_CHAR(X) AS X_ALIAS_LEAF
                , LEVEL AS LVL
      FROM MY_TABLE
 LEFT JOIN MY_TABLE_BIS MY_TABLE_BIS_ALIAS ON MY_TABLE_BIS_ALIAS.MY_ID = COL_X
 LEFT JOIN OTHER_TABLE 
        ON OTHER_TABLE.MY_ID = COL_X
CONNECT BY (PRIOR ID_SON = ID_FATHER)
       AND LEVEL <= MAXDEPTH
START WITH ID_FATHER 
        IN (SELECT AN_ID AS ID_FATHER FROM BIG_TABLE)
选择
不同于作为X_别名的_CHAR(CONCAT(@ROOT,SYS_CONNECT_BY_PATH(CONCAT('C_',X),')))
,作为X_别名_父,连接到_CHAR(CONCAT(@ROOT,之前的SYS_CONNECT_BY_PATH(CONCAT('C_',X),'.'))
,将_CHAR(X)作为X_别名_LEAF
,级别为LVL
从我的桌子上
左键连接MY_TABLE_BIS MY_TABLE_BIS_别名在MY_TABLE_BIS_别名上。MY_ID=COL_X
左连接其他表
在另一张表上。MY_ID=COL_X
连接方式(先前的ID\u子=ID\u父)

级别都可以使用多个函数来解决,而且递归非常简单,(注意,T-SQL中的最大递归级别是32)

假设我们有下表:(给一家非常小的公司)

我们只需要一个函数来检查两个ID之间是否存在链接,另一个函数给出从一个ID到另一个ID的路径

第一个函数使用递归非常简单:

Create Function dbo.Do_WE_Have_path(@id int, @boss_id int, @max_level int) returns int
Begin
  declare @res int, @man int
  set @res = 0
  if @id = @boss_id 
    set @res = 1
  else if @max_level > 0 
  Begin
    Select @man=manager_id from Employees where id=@id
    set @res = Do_WE_Have_path(@man, @boss_id, @max_level-1) --recursion
  End
  return res 
End
使用上述函数,我们可以选择连接短于或等于指定级别的所有实体,因此现在我们可以编写一个方法来构建路径(如果存在),请注意,不存在的路径应使用上述方法进行过滤

Create Function dbo.Make_The_path(@id int, @boss_id int, @max_level int) returns varchar(max)
Begin
  declare @res varchar(max), @man int
  select @res = name from Employees where id=@id
  if max_level > 0 AND @id <> @boss_id
  Begin 
    select @man = manager_id from Employees where id = @id
    set @res = dbo.Make_The_path(@man, @boss_id, max_level-1) + '/' + @res
  End
  return @res
End

这两个函数都可以合并为一个函数,也许您需要为每个结构重新编写它,但重要的是这是可能的

第一个查询未引用
listAllCfaCfq
。请为表发布
DDL
。能否提供表数据如果您在SQL Server中使用hierachyid(我不知道,因为您还没有发布表结构),那么您可以使用CAST(hierarchyid作为nvarchar(100))为每行显示如下路径:/2/1/2/1/不知道为什么有这么多人对此进行了投票。在提供DDL之前,它应该关闭。您已经回答了自己的问题,为什么不把它作为一个答案呢。有人纠正你错误的可能性很小。
Create Function dbo.Do_WE_Have_path(@id int, @boss_id int, @max_level int) returns int
Begin
  declare @res int, @man int
  set @res = 0
  if @id = @boss_id 
    set @res = 1
  else if @max_level > 0 
  Begin
    Select @man=manager_id from Employees where id=@id
    set @res = Do_WE_Have_path(@man, @boss_id, @max_level-1) --recursion
  End
  return res 
End
Create Function dbo.Make_The_path(@id int, @boss_id int, @max_level int) returns varchar(max)
Begin
  declare @res varchar(max), @man int
  select @res = name from Employees where id=@id
  if max_level > 0 AND @id <> @boss_id
  Begin 
    select @man = manager_id from Employees where id = @id
    set @res = dbo.Make_The_path(@man, @boss_id, max_level-1) + '/' + @res
  End
  return @res
End
Select dbo.Make_The_path(id, 1, 3) Where Do_WE_Have_path(id, 1, 3)=1