Sql server 递归CTE SQL(父-子)
我正在使用SQL Server 2012 位置明细表Sql server 递归CTE SQL(父-子),sql-server,tsql,sql-server-2012,recursive-cte,Sql Server,Tsql,Sql Server 2012,Recursive Cte,我正在使用SQL Server 2012 位置明细表 OID LOCATIONNAME PARENTID 1 GLOBAL 0 2 NORTH 1 3 SOUTH 1 4 NORTH1 2 5 SOUTH1 3 LOCATIONSITECONFIG表 OID LOCATIONID SIT
OID LOCATIONNAME PARENTID
1 GLOBAL 0
2 NORTH 1
3 SOUTH 1
4 NORTH1 2
5 SOUTH1 3
LOCATIONSITECONFIG表
OID LOCATIONID SITENAME
1 2 TEST
OID LOCATIONDETAILOID SITENAME
1 2 TEST
2 1 NEWTEST
我使用递归CTE查询
;WITH LOCALSITEHIERARCHY AS
(
SELECT A.OID
,A.PARENTOID
,CAST(A.LOCATIONNAME + ' ( ' + LSC.SITENAME + ' )' AS NVARCHAR(100)) AS NAME
,LSC.OID AS SITEOID
FROM LOCATIONDETAIL A
INNER JOIN LOCATIONSITECONFIG LSC
ON LSC.LOCATIONDETAILOID = A.OID
WHERE
LSC.SITENAME <> 'GLOBAL' AND LSC.RECSTATUS = 'A'
UNION ALL
SELECT
A.OID
,A.PARENTOID
,CAST(A.LOCATIONNAME AS NVARCHAR(100))
,LH.SITEOID
FROM LOCATIONDETAIL A
INNER JOIN LOCALSITEHIERARCHY LH ON A.PARENTOID = LH.OID
)
SELECT * FROM LOCALSITEHIERARCHY
上述查询返回
全球,北,北1,南1,南1
以及NORTH(测试)和NORTH1(记录副本)
我希望查询返回
全球、北(测试)、北1、南1、南1
如果子项已创建站点,则应忽略查询。请将您的CTE更改为以GLOBAL作为锚定成员开始,以提供帮助。递归部分需要调整以包括SITENAME,这是通过合并(如果位置没有SITENAME)和子查询完成的
with LOCALSITEHIERARCHY
as (
select A.OID
, A.PARENTOID
, cast(A.LOCATIONNAME+' ( '+LSC.SITENAME+' )' as nvarchar(100)) as NAME
, LSC.OID as SITEOID
, cast(row_number() over(partition by parentoid order by A.LOCATIONNAME) as varchar(max)) as [PATH]
from LOCATIONDETAIL as A
inner join LOCATIONSITECONFIG as LSC on LSC.LOCATIONDETAILOID = A.OID
where 1 = 1
and A.PARENTOID is null
and LSC.RECSTATUS = 'A'
union all
select A.OID
, A.PARENTOID
, cast(coalesce(A.LOCATIONNAME+' ( '+
(
select SITENAME
from LOCATIONSITECONFIG C
where C.LOCATIONDETAILOID = A.OID
)+' )', A.LOCATIONNAME) as nvarchar(100)) as NAME
, coalesce((select C.OID from LOCATIONSITECONFIG C where C.LOCATIONDETAILOID = A.OID),NULL) as SITEOID
, [path]+'-'+cast(row_number() over(partition by A.parentoid order by A.LOCATIONNAME) as varchar(max))
from LOCATIONDETAIL as A
inner join LOCALSITEHIERARCHY as LH on A.PARENTOID = LH.OID)
select * from LOCALSITEHIERARCHY order by [PATH];
结果输出如下图所示
将您的CTE更改为以GLOBAL作为锚定成员开始。递归部分需要调整以包括SITENAME,这是通过合并(如果位置没有SITENAME)和子查询完成的
with LOCALSITEHIERARCHY
as (
select A.OID
, A.PARENTOID
, cast(A.LOCATIONNAME+' ( '+LSC.SITENAME+' )' as nvarchar(100)) as NAME
, LSC.OID as SITEOID
, cast(row_number() over(partition by parentoid order by A.LOCATIONNAME) as varchar(max)) as [PATH]
from LOCATIONDETAIL as A
inner join LOCATIONSITECONFIG as LSC on LSC.LOCATIONDETAILOID = A.OID
where 1 = 1
and A.PARENTOID is null
and LSC.RECSTATUS = 'A'
union all
select A.OID
, A.PARENTOID
, cast(coalesce(A.LOCATIONNAME+' ( '+
(
select SITENAME
from LOCATIONSITECONFIG C
where C.LOCATIONDETAILOID = A.OID
)+' )', A.LOCATIONNAME) as nvarchar(100)) as NAME
, coalesce((select C.OID from LOCATIONSITECONFIG C where C.LOCATIONDETAILOID = A.OID),NULL) as SITEOID
, [path]+'-'+cast(row_number() over(partition by A.parentoid order by A.LOCATIONNAME) as varchar(max))
from LOCATIONDETAIL as A
inner join LOCALSITEHIERARCHY as LH on A.PARENTOID = LH.OID)
select * from LOCALSITEHIERARCHY order by [PATH];
结果输出如下图所示
您想返回全球(最新)、北方(测试)、北方1、南方1吗?您想返回全球(最新)、北方(测试)、北方1、南方1吗?谢谢Koen,回答得很好。让我试着回你电话,我试过解决办法。应该相应地显示SiteOID,这里是LOCATIONSITECONFIG中的最后一个OID正在重复。我想让NORTH(Test)将siteoid设置为1,将Global(NewTEST)设置为2。你能帮个忙吗?你的意思是第四列SITEOID应该是1,2,NULL,NULL,NULL?如果位置存在sitename,则仅显示siteoid?谢谢Koen,答案草拟得很好。让我试着回你电话,我试过解决办法。应该相应地显示SiteOID,这里是LOCATIONSITECONFIG中的最后一个OID正在重复。我想让NORTH(Test)将siteoid设置为1,将Global(NewTEST)设置为2。你能帮个忙吗?你的意思是第四列SITEOID应该是1,2,NULL,NULL,NULL?如果位置存在sitename,则仅显示siteoid?