2012-12-04 49 views
2

我有一個Locations表是行政區劃的自我加入的層次結構。像State,County,TownLocationIdPK這個table它被用作Foreign keyjoining table。加入表有ProjectIdLocationsId,項目可以在任何級別的位置,所以加入表可以有縣,鎮等。我想找出用作FK的位置root-parent(State)。 請使用以下sql爲樣本(Management Studio中的複製/粘貼)查找根自我連接表的父母列用作外鍵

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

我認爲下面會爲你工作:

(我已將所有@表格更改爲#表格,只是爲了方便)

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 
0

您需要使用Common Table Expressions在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 
+0

對不起,但沒有工作。 – Kashif

+0

我沒有測試它,它只是您需要使用的SQL Server功能的一個示例,請嘗試在Google上搜索「SQL Server常用表表達式」,您會發現很多示例。 – remigio

+0

哦,我明白了,謝謝你! – Kashif