2

我有一个Locations表,它是自连接的,用于制作行政区划的层次结构。Like State, County, Townetc. LocationId属于PK这个table,它被用作Foreign keyin joining table。加入表有ProjectIdLocationsId,项目可以在任何级别的位置,所以加入表可以有县、镇等。我想找出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
4

2 回答 2

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
于 2012-12-04T09:56:42.023 回答
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
于 2012-12-04T10:12:46.440 回答