从自联接表获取Parent的父项的父项

时间:2011-02-01 09:27:53

标签: sql tsql sql-server-2008 sql-server-2000

请复制并运行以下脚本。

DECLARE @Locations TABLE
(
    LocationId INT,
    LocationName VARCHAR(50),
    ParentId INT
)

INSERT INTO @Locations SELECT 1, 'Europe', NULL
INSERT INTO @Locations SELECT 2, 'UK', 1
INSERT INTO @Locations SELECT 3, 'England', 2
INSERT INTO @Locations SELECT 4, 'Scotland', 2
INSERT INTO @Locations SELECT 5, 'Wales', 2
INSERT INTO @Locations SELECT 6, 'Cambridgeshire', 3
INSERT INTO @Locations SELECT 7, 'Cambridge', 6
INSERT INTO @Locations SELECT 8, 'North Scotland', 4
INSERT INTO @Locations SELECT 9, 'Inverness', 8
INSERT INTO @Locations SELECT 10, 'Somerset', 3
INSERT INTO @Locations SELECT 11, 'Bath', 10
INSERT INTO @Locations SELECT 12, 'Poland', 1
INSERT INTO @Locations SELECT 13, 'Warsaw', 12

我需要以下类型的结果

enter image description here

感谢。

1 个答案:

答案 0 :(得分:4)

你无法用当前的数据集做到这一点;你怎么知道在LocationId=11的情况下,你有一个县/国/大陆,而在LocationId=13的情况下,没有一个县 - 只有一个国家/大陆?

您如何知道从输出结果中“跳过”SomersetNorth Scotland等条目?

您在这里肯定需要更多信息....

使用此递归CTE(公用表表达式)查询,您可以将层次结构中的“阶梯”提升到顶部,对于任何给定的位置:

DECLARE @LocID INT = 13

;WITH LocationHierarchy AS
(
    SELECT LocationId, LocationName, ParentId, 1 AS 'Level'
    FROM @Locations
    WHERE LocationId = @LocID

    UNION ALL

    SELECT l.LocationId, l.LocationName, l.ParentId, lh.Level + 1 AS 'Level'
    FROM @Locations l
    INNER JOIN LocationHierarchy lh ON lh.ParentId = l.LocationId
)
SELECT
    LocationName,
    LocationId,
    Level
FROM LocationHierarchy

这个CTE适用于SQL Server 2005及以上的SQL Server 2000,不幸的是,你运气不好(升级的时间!!)。

这再次允许您走向单个条目的层次结构 - 但它不可能返回您正在寻找的数据集 - 没有足够的信息来从当前数据中确定这一点。

对于@LocID=13(华沙),您可以获得此输出:

LocationName    LocationId  Level
  Warsaw               13             1
  Poland               12             2
  Europe                1             3

@LocID=7(剑桥),你得到:

LocationName    LocationId  Level
  Cambridge             7             1
  Cambridgeshire        6             2
  England               3             3
  UK                    2             4
  Europe                1             5

从那时起,你必须在你的应用中使用一些智能来获得你正在寻找的确切输出。