Sql server 递归CTE SQL(父-子)

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

我正在使用SQL Server 2012

位置明细表

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?