как получить полное имя человека из базы данных - PullRequest
0 голосов
/ 31 августа 2018

У меня есть эти таблицы

персона таблица со следующими данными

person_id    description

 1          first in the family
 2          second in the family
 3          third in the family
 4          fourth int the family
 5          fifth in the family

person_name таблица со следующими данными

person_id  first_name

  1        Santiago
  2         Lautaro
  3          Lucas
  4          Franco
  5          Agustín

папа таблица со следующими данными

person_father_id  description
    1              father of Lautaro
    2              father of Lucas
    3              father of Franco
    4              father of Agustín

дети таблица со следующими данными

 person_child_id   person_father_id
      2                 1
      3                 2
      4                 3
      5                 4

как получить полное имя (Agustín Franco Lucas Lautaro Santiago) человека, у которого person_id 4 в запросе выбора pl / sql. основной стол человек

1 Ответ

0 голосов
/ 31 августа 2018

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

select p.person_id, pn.first_name, c.person_father_id
from person p
join person_name pn on pn.person_id = p.person_id
left join children c on c.person_child_id = p.person_id;

 PERSON_ID FIRST_NAME PERSON_FATHER_ID
---------- ---------- ----------------
         2 Lautaro                   1
         3 Lucas                     2
         4 Franco                    3
         5 Agustín                   4
         1 Santiago                   

и с этим в качестве основы для иерархического запроса:

select trim(sys_connect_by_path(first_name, ' ')) as whole_name
from (
  select p.person_id, pn.first_name, c.person_father_id
  from person p
  join person_name pn on pn.person_id = p.person_id
  left join children c on c.person_child_id = p.person_id
)
where connect_by_isleaf = 1
start with person_id = 4
connect by person_id = prior person_father_id;

WHOLE_NAME                                        
--------------------------------------------------
Franco Lucas Lautaro Santiago

Или вы можете сделать иерархический запрос сам по себе дополнительным подзапросом, а затем присоединиться к именам и объединить это:

select listagg(pn.first_name, ' ') within group (order by lvl) as whole_name
from (
  select person_id, level as lvl
  from (
    select p.person_id, c.person_father_id
    from person p
    left join children c on c.person_child_id = p.person_id
  )
  start with person_id = 4
  connect by person_id = prior person_father_id
) t
join person_name pn on pn.person_id = t.person_id;

WHOLE_NAME                                        
--------------------------------------------------
Franco Lucas Lautaro Santiago

Обратите внимание, что с обоими из них вы должны присоединиться к таблицам, прежде чем сможете выполнять фильтрацию по начальному идентификатору (start with, а не where, поскольку это иерархически). Это означает, что с большими таблицами это может привести к тому, что вы будете выполнять больше работы, чем вам действительно нужно или ожидаете.

Или вы можете сделать то же самое с рекурсивным факторингом подзапроса (рекурсивный CTE), если вы предпочитаете, и вы используете Oracle 11gR2 или выше:

with r (person_id, person_father_id, lvl) as (
  select p.person_id, c.person_father_id, 1
  from person p
  left join children c on c.person_child_id = p.person_id
  where p.person_id = 4
  union all
  select p.person_id, c.person_father_id, r.lvl + 1
  from r
  join person p on p.person_id = r.person_father_id
  left join children c on c.person_child_id = p.person_id
)
select listagg(pn.first_name, ' ') within group (order by lvl) as whole_name
from r
join person_name pn on pn.person_id = r.person_id;

WHOLE_NAME                                        
--------------------------------------------------
Franco Lucas Lautaro Santiago

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

Подробнее о иерархических запросах и рекурсивных факторингах подзапросов .

...