Как построить родительско-дочерние иерархии (начиная с root) на SQL сервере? - PullRequest
1 голос
/ 02 марта 2020

Я пытаюсь получить путь от узла root к его дочерним элементам, используя сервер SQL.

Исходные данные выглядят следующим образом:

Исходные данные

Цель должна выглядеть следующим образом:

Данные цели

Поскольку я собираюсь реализовать это в инструменте ETL исключительно с использованием преобразований ETL, Я хотел бы достичь этого результата без использования эквивалентного подхода CONNECT BY. Ниже запрос получает мне результат и еще несколько записей:

select case when level02.geography_02 is not NULL
    then '3'
    else case when level01.geography_02 is not null
                then '2'
                else case when root.geography_02 is not null
                    then '1'
                    end 
        end
end as levels,
root.geography_01 as root, root.geography_02 as super_parent,
case when level01.geography_02 is not null
        then level01.geography_02
        else ''
        end as parent,
case when level02.geography_02 is not null
        then level02.geography_02
        else ''
        end as child
from geo_table root
left join geo_table level01
on root.geography_02 = level01.geography_01
left join geo_table level02
on level01.geography_02 = level02.geography_01

Подскажите пожалуйста, как получить желаемый результат?

1 Ответ

0 голосов
/ 02 марта 2020

Я думаю, вам просто нужна фильтрация. Тем не менее, остальная часть вашего запроса также может быть немного упрощена - в частности, с помощью COALESCE():

select (case when level02.geoghraphy_02 is not NULL then '3'
             when level01.geoghraphy_02 is not null then '2'
             when root.geoghraphy_02 is not null then '1'
        end) as levels,
       root.geoghraphy_01 as root,
       root.geoghraphy_02 as super_parent,
       coalesce(level01.geography_02, '') as parent,
       coalesce(level02.geography_02, '') as child
from geo_table root left join
     geo_table level01
     on root.geography_02 = level01.geography_01 left join
     geo_table level02
     on level01.geography_02 = level02.geography_01
where not exists (select 1
                  from geo_table gt
                  where gt.geography_02 = root.geography_01
                 );

По сути, вам просто нужно ограничить "root" фактическим root записей. Вы на самом деле справились с более сложной частью логики c (по моему мнению).

...