Oracle SYS_CONNECT_BY_PATH等效查询到SQL Server

时间:2017-05-09 14:17:19

标签: sql-server tsql hierarchical-data recursive-query

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

$CurrentValue = [Environment]::GetEnvironmentVariable("PSModulePath", "Machine")
[Environment]::SetEnvironmentVariable("PSModulePath", $CurrentValue + ";C:\MyPSModule", "Machine")

以下是我使用this website

获得的内容
    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)

我更改了表格的名称,这样做可能会犯错误,请在评论中告诉我这一点

1 个答案:

答案 0 :(得分:0)

所有这些都可以使用几个函数来解决,并且只需进行一些递归即可,(请注意,T-SQL中的最大递归级别为32)

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

TableName: Employees
id.....name..............manager_id
1      Big Boss          NULL
2      Sales Manager     1
3      Support Manager   1
4      R&D Manager       1               
5      Sales man         2
6      Support man       3
7      R&D Team leader   4
8      QA Team leader    4
9      C Developer       7
10     QA man            8
11     Java Developer    7      

我们只需要一个函数来检查2个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

现在我们可以使用这两个功能来获取从老板到工人的路径:

Select dbo.Make_The_path(id, 1, 3) Where Do_WE_Have_path(id, 1, 3)=1    

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