Подзапрос SQL с использованием родительского значения в поле "Начать с"

Я пытаюсь объединить несколько запросов, но сталкиваюсь с проблемой, независимо от того, каким образом я пытаюсь соединить их вместе. Вот макет из двух:

Запрос 1 (Получить все G и связанные R):

select distinct 
    a.g_id, 
    a.g_name,
    b.r_name, 
    b.r_id
from 
    g_tab a, 
    r_tab b,
    f_tab c
where
    a.g_id = b.g_id
    and b.r_id = c.r_id
    and c.f_id = 7
order by a.g_id 

Запрос 2 (Обход иерархии и фильтрация по определенной группе):

with parentGs as 
(
    select 
        f.g_id,
        f.g_name
    from 
        g_tab f
    where  
        f.delete_indicator is null
    connect by
       prior f.parent_g_id = f.g_id
    start with
        f.g_id = 22 --DO NOT WANT THIS HARDCODED
)

select 
    d.g_name
from
    parentGs d,
    g_group_members_tab e
where 
    d.g_id = e.member_g_id
    and e.g_group_description = 'test'

Я не хочу изменять счетчик возврата для запроса 1, но хотел бы присоединиться к g_name из запроса 2 и добавить его в качестве нового столбца с псевдонимами.

Вот один пример того, что я пытаюсь получить, но не работает из-за того, что g_id называют "неверным идентификатором" в "начать с". Я знаю, что родительские значения действительны только в одном подзапросе, но все равно получат ту же ошибку, если реструктурируют только с одним подзапросом (в данном случае в "from"):

select distinct 
    a.g_id, 
    a.g_name,
    b.r_name, 
    b.r_id,
    (select 
        d.g_name
    from
        (select 
            f.g_id,
            f.g_name
        from 
            g_tab f
        where  
            f.delete_indicator is null
        connect by
           prior f.parent_g_id = f.g_id
        start with
            f.g_id = a.g_id) d, --THIS GIVES INVALID IDENTIFIER
        g_group_members_tab e
    where 
        d.g_id = e.member_g_id
        and e.g_group_description = 'test') as parent_g_name
from 
    g_tab a, 
    r_tab b,
    f_tab c
where
    a.g_id = b.g_id
    and b.r_id = c.r_id
    and c.f_id = 7
order by a.g_id 

Любая помощь в объединении этих двух запросов будет принята с благодарностью. Моя целевая платформа - Oracle 11g. Большое спасибо!

* Обновить *

Вот несколько примеров данных SQL Fiddle:

create table g_tab
( 
  g_id number(9),
  g_name varchar2(50),
  parent_g_id number(9),
  delete_indicator char(1)
)
/
create table g_group_members_tab
( 
  member_g_id number(9),
  g_group_description varchar2(50)
)
/
create table r_tab
( 
  r_id number(9),
  r_name varchar2(50),
  g_id number(9)
)
/
create table f_tab
( 
  f_id number(9),
  f_name varchar2(50),
  r_id number(9)
)
/
insert into g_tab (g_id, g_name, parent_g_id) values (0, 'a', null)
/
insert into g_tab (g_id, g_name, parent_g_id) values (1, 'b', 0)
/
insert into g_tab (g_id, g_name, parent_g_id) values (2, 'c', 1)
/
insert into g_tab (g_id, g_name, parent_g_id) values (3, 'd', null)
/
insert into g_tab (g_id, g_name, parent_g_id) values (4, 'e', 3)
/
insert into g_tab (g_id, g_name, parent_g_id) values (5, 'f', 4)
/
insert into g_tab (g_id, g_name, parent_g_id) values (6, 'g', null)
/
insert into g_group_members_tab (member_g_id, g_group_description) values (1, 'test')
/
insert into g_group_members_tab (member_g_id, g_group_description) values (3, 'test')
/
insert into r_tab (r_id, r_name, g_id) values (0, 'r', 0)
/
insert into r_tab (r_id, r_name, g_id) values (0, 'r', 1)
/
insert into r_tab (r_id, r_name, g_id) values (0, 'r', 2)
/
insert into r_tab (r_id, r_name, g_id) values (0, 'r', 3)
/
insert into r_tab (r_id, r_name, g_id) values (0, 'r', 4)
/
insert into r_tab (r_id, r_name, g_id) values (1, 'rr', 5)
/
insert into r_tab (r_id, r_name, g_id) values (0, 'r', 6)
/
insert into f_tab (f_id, f_name, r_id) values (7, 'f', 0)
/
insert into f_tab (f_id, f_name, r_id) values (7, 'f', 1)

Желаемый результат:

g_id    g_name    r_name    r_id    parent_g_name
0       a         r         0       null
1       b         r         0       b   
2       c         r         0       b
3       d         r         0       d
4       e         r         0       d
5       f         rr        1       d
6       g         r         0       null

1 ответ

Решение

Вы можете пройти большую часть пути, просто превратив свой подзапрос во встроенное представление:

select distinct 
    a.g_id, 
    a.g_name,
    b.r_name, 
    b.r_id,
    d.g_name as parent_g_name
from 
    g_tab a, 
    r_tab b,
    f_tab c,
    (
        select 
            f.g_id,
            f.g_name,
            connect_by_root f.g_id as root_g_id
        from 
            g_tab f
        where  
            f.delete_indicator is null
        connect by
            prior f.parent_g_id = f.g_id
    ) d,
    g_group_members_tab e
where
    a.g_id = b.g_id
    and b.r_id = c.r_id
    and c.f_id = 7
    and a.g_id = d.root_g_id
    and d.g_id = e.member_g_id
    and e.g_group_description = 'test'
order by a.g_id

Который дает:

      G_ID G_NAME R_NAME       R_ID PARENT_G_NAME
---------- ------ ------ ---------- -------------
         1 b      r               0 b             
         2 c      r               0 b             
         3 d      r               0 d             
         4 e      r               0 d             
         5 f      rr              1 d             

Вы пропускаете нули, поэтому вам нужно превратить это во внешнее соединение; но вам нужно присоединиться d в e в этом. Все это намного приятнее с объединениями ANSI:

select distinct 
    a.g_id, 
    a.g_name,
    b.r_name, 
    b.r_id,
    d.g_name as parent_g_name
from g_tab a
join r_tab b
on   b.g_id = a.g_id
join f_tab c
on   c.r_id = b.r_id
left join (
    select
        e.g_id,
        e.g_name,
        e.root_g_id
    from (
        select 
            f.g_id,
            f.g_name,
            connect_by_root f.g_id as root_g_id
        from 
            g_tab f
        where  
            f.delete_indicator is null
        connect by
            prior f.parent_g_id = f.g_id) e
    join g_group_members_tab f
    on   f.member_g_id = e.g_id
    where f.g_group_description = 'test'
    ) d
on  d.root_g_id = a.g_id
where c.f_id = 7
order by a.g_id 

Который дает:

      G_ID G_NAME R_NAME       R_ID PARENT_G_NAME
---------- ------ ------ ---------- -------------
         0 a      r               0               
         1 b      r               0 b             
         2 c      r               0 b             
         3 d      r               0 d             
         4 e      r               0 d             
         5 f      rr              1 d             
         6 g      r               0               

SQL Fiddle demo.

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