Oracle "начать с" рекурсии снизу вверх эквивалент SQL Server

Я видел много постов, в которых рассказывалось, как преобразовать оператор Oracle "подключиться по предыдущему" в общее табличное выражение SQL Server. Тем не менее, у меня есть оператор Oracle "connect by before", в котором есть предложение "start with fieldname in ('value1','value2','value3')" ", и я не вижу примеров того, как преобразовать это в SQL Server. Я считаю, что это считается рекурсией "снизу вверх".

Вот мой запрос Oracle:

select distinct KEY
from MY_HIERARCHICAL_TABLE
connect by prior PARENT_KEY = KEY
start with KEY in ('CHILD-A1','CHILD-C1')

Образец таблицы:

MY_HIERARCHICAL_TABLE
---------------------
KEY
PARENT_KEY

Пример данных:

KEY       PARENT_KEY
--------- ----------
TOP       null
PARENT-A  TOP
CHILD-A1  PARENT-A
CHILD-A2  PARENT-A
PARENT-B  TOP
CHILD-B1  PARENT-B
PARENT-C  TOP
CHILD-C1  PARENT-C

Мой запрос должен работать следующим образом:

  • ДЕТЯМ-А1 и его родители будут включены: ТОП, РОДИТЕЛЬ-А, ДЕТЯМ-А1
  • ДЕТЯМ-С1 и его родители будут включены: ТОП, РОДИТЕЛЬ-С, ДЕТЯМ-С1
  • CHILD-A2 будет исключен, так как CHILD-A2 нет в моем списке. PARENT-A будет включен, потому что CHILD-A1 находится в моем списке.
  • PARENT-B & CHILD-B1 будут исключены, поскольку CHILD-B1 нет в моем списке.
  • Окончательный, отдельный набор результатов будет TOP, PARENT-A, CHILD-A1, PARENT-C, CHILD-C1

Я надеюсь, что я объяснил это хорошо. Я искал примеры, которые бы соответствовали этому сегодня. Любой вклад будет принята с благодарностью.

1 ответ

Решение

Достаточно легко выбрать записи, не знаю, как их отсортировать

with 
param as (
  select *
  from ( values 
        ('CHILD-A1'),('CHILD-C1')
       ) v (child)
),
dat as (
  select * 
  from ( values 
        ('TOP'     , null ),
        ('PARENT-A','TOP' ),
        ('CHILD-A1','PARENT-A'),
        ('CHILD-A2','PARENT-A'),
        ('PARENT-B','TOP' ),
        ('CHILD-B1','PARENT-B'),
        ('PARENT-C','TOP'),
        ('CHILD-C1','PARENT-C')
       ) v(child,parent)
), 
rec as (
  select dat.* 
  from dat join param on dat.child=param.child
  union all 
  select dat.*
  from dat join rec on dat.child=rec.parent
)  
select distinct * from rec

http://sqlfiddle.com/

Другие вопросы по тегам