我有一个Locations
表,它是自行连接的,构成了行政区划的层次结构。与State
,County
,Town
等相同。
LocationId
PK
为此table
的{{1}},Foreign key
中的joining table
使用ProjectId
。加入表有LocationsId
和root-parent(State)
,项目可以在任何级别的位置,因此加入表可以有县,镇等。我想找出用作FK的位置sql
。
请使用以下DECLARE @Locations TABLE (LocationId INT, LocationName VARCHAR(30), ParentId INT, LocLevel INT)
INSERT INTO @Locations
Values(1, 'State1', NULL, 1),
(2, 'State1-County1', 1, 2),
(3, 'State1-County1-Town1', 2, 3),
(4, 'State1-County1-Town1-Muncip-1', 3, 4),
(5, 'State1-County2', 1, 2),
(6, 'State1-County2-Town1', 5, 3),
(7, 'State1-County2-Town1-Muncip-1', 6, 4),
(8, 'State2', NULL, 1),
(9, 'State2-County1', 8, 2),
(10, 'State2-County1-Town1', 9, 3),
(11, 'State2-County1-Town1-Muncip-1', 10, 4)
DECLARE @ProjectLocations TABLE (ProjectLocationId INT, ProjectId INT, LocationId INT)
INSERT INTO @ProjectLocations
VALUES(1, 1, 2),
(2, 1, 3),
(3, 1, 4),
(4, 1, 11),
(5, 2, 3),
(6, 2, 11),
(7, 3, 10),
(8, 4, 11),
(9, 5, 9)
SELECT * FROM @Locations
SELECT * FROM @ProjectLocations
作为样本。(在管理工作室中复制/粘贴)
DECLARE @FirstOutput TABLE (ProjectLocationId INT, ProjectId INT, LocationId INT, RootParentId INT)
SELECT * FROM @FirstOutput
这应该是
{{1}}
答案 0 :(得分:1)
我认为以下内容适合您:
(为方便起见,我已将所有@表更改为#表)
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
答案 1 :(得分:0)
您需要一个递归查询,在SQL Server中使用公用表表达式实现。这是一个例子:
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