Sql server Oracle SYS\u CONNECT\u BY\u路径等效查询到SQL Server
我正在尝试将涉及Oracle SYS_CONNECT_BY_PATH语法的复杂查询转换为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), '.')
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