Получить родитель родительского из таблицы самостоятельного соединения - PullRequest
1 голос
/ 01 февраля 2011

Pleae скопируйте и запустите следующий скрипт.

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 Ответ

4 голосов
/ 01 февраля 2011

Нет способа сделать это с текущим набором данных; откуда вы знаете, что в случае LocationId=11 у вас есть округ / страна / континент, а в случае LocationId=13 нет графства - только страна / континент ??

А как вы знаете, что "пропустить" записи для Somerset, North Scotland и т. Д. Из вашего результата вывода ??

Вам определенно нужно больше информации здесь ...

С помощью этого рекурсивного запроса CTE (Common Table Expression) вы можете поднять «лестницу» вверх по иерархии для любого данного местоположения:

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

С этого момента вам придется использовать некоторые смарты в вашем приложении, чтобы получить именно тот результат, который вы ищете.

...