Sql 查找用作外键的自联接表列的根父级
我有一个Sql 查找用作外键的自联接表列的根父级,sql,sql-server-2008,tsql,common-table-expression,Sql,Sql Server 2008,Tsql,Common Table Expression,我有一个位置表,它是自连接的,用于制作行政区划层次结构。像州,县,镇等。 LocationId是该表的PK,在联接表中用作外键。联接表具有ProjectId和LocationsId,项目可以位于任何级别的位置,因此联接表可以具有县、镇等。我想找出用作FK的位置的根父(州)。 请使用以下sql作为示例。(在ManagementStudio中复制/粘贴) 这个应该放出去 DECLARE @FirstOutput TABLE (ProjectLocationId INT, ProjectId INT,
位置
表,它是自连接的,用于制作行政区划层次结构。像州,县
,镇
等。
LocationId
是该表的PK
,在联接表中用作外键。联接表具有ProjectId
和LocationsId
,项目可以位于任何级别的位置,因此联接表可以具有县、镇等。我想找出用作FK的位置的根父(州)
。
请使用以下sql
作为示例。(在ManagementStudio中复制/粘贴)
这个应该放出去
DECLARE @FirstOutput TABLE (ProjectLocationId INT, ProjectId INT, LocationId INT, RootParentId INT)
SELECT * FROM @FirstOutput
我认为以下几点对你有用:
(为了方便起见,我把所有的@tables都改成了#tables)
您需要一个递归查询,在SQLServer中使用公共表表达式实现。这是一个例子:
WITH FirstOutput (ProjectLocationId,ProjectId,LocationId,RootParentId) AS
(
SELECT
PL.ProjectLocationId,PL.ProjectId,L.LocationId,L.LocationId
FROM
ProjectLocations PL
INNER JOIN
Locations L ON PL.LocationId=L.LocationId
WHERE
L.ParentId IS NULL
UNION ALL
SELECT
PL.ProjectLocationId,PL.ProjectId,L.LocationId,F.RootParentId
FROM
ProjectLocations PL
INNER JOIN
Locations L ON PL.LocationId=L.LocationId
INNER JOIN
FirstOutput F ON L.ParentId=F.LocationId
)
SELECT * FROM FirstOutput
我没有测试它,它只是您需要使用的SQL Server功能的一个示例,尝试在Google中搜索SQL Server公共表表达式
,您会发现很多示例。
WITH LocationHierachy (LocationId, ParentId)
AS
(
--Anchor
SELECT L.LocationId, ISNULL(L.ParentId, L.LocationId)
FROM #Locations L
UNION ALL
--Recurse
SELECT H.LocationId, L.ParentId
FROM LocationHierachy H
JOIN #Locations L
ON L.LocationId = H.ParentId
)
SELECT PL.ProjectLocationId,
PL.ProjectId,
PL.LocationId,
H.ParentId as RootParentId
FROM #ProjectLocations PL
JOIN LocationHierachy H
ON PL.LocationId = H.LocationId
JOIN #Locations L
ON H.ParentId = L.LocationId
WHERE L.ParentId IS NULL
WITH FirstOutput (ProjectLocationId,ProjectId,LocationId,RootParentId) AS
(
SELECT
PL.ProjectLocationId,PL.ProjectId,L.LocationId,L.LocationId
FROM
ProjectLocations PL
INNER JOIN
Locations L ON PL.LocationId=L.LocationId
WHERE
L.ParentId IS NULL
UNION ALL
SELECT
PL.ProjectLocationId,PL.ProjectId,L.LocationId,F.RootParentId
FROM
ProjectLocations PL
INNER JOIN
Locations L ON PL.LocationId=L.LocationId
INNER JOIN
FirstOutput F ON L.ParentId=F.LocationId
)
SELECT * FROM FirstOutput