Как получить запись root в базе данных Oracle - PullRequest
0 голосов
/ 23 апреля 2020

Начиная с базового c узла (или листа), как получить root узел?

SELECT 
    ID,MSG_ID,PARENT_ID 
FROM 
    TABLE_X
CONNECT BY PRIOR PARENT_ID = ID;

ID  MSG_ID                              PARENT_ID
4   3                                   NULL
5   93bea0f71b07-4037-9009-f148fa39bb62 4
4   3                                   NULL
6   6f5f5d4ab1ec-4f00-8448-7a6dfa6461b2 4
4   3                                   NULL    
7   3                                   NULL
8   7e0fae569637-4d29-9075-c273eb39ae8e 7
7   3                                   NULL
9   8a3e7485b3e8-45b1-a31d-c52fd32111c0 7
7   3                                   NULL
10  fcc622d5af92-4e61-8d7c-add3da359a8b 7
7   3                                   NULL

Как получить root msg_id?

Ответы [ 2 ]

0 голосов
/ 23 апреля 2020

Вы были на правильном пути, но вам не хватает двух основных ингредиентов.

Во-первых, чтобы указать начальную точку, вам нужно использовать предложение start with. Очевидно, это будет что-то вроде start with id = <input value>. Вы не сказали нам, как вы предоставите входное значение. Наиболее распространенным подходом является использование переменных связывания (лучше всего по многим причинам); Я назвал переменную связывания input_id в запросе ниже.

Во-вторых, вам нужна только «последняя» строка (поскольку вы перемещаетесь по дереву в противоположном направлении: к root, а не от root, поэтому root теперь является "листом", когда вы перемещаетесь таким образом). Для этого вы можете использовать псевдостолбец connect_by_isleaf в предложении where.

Итак, запрос должен выглядеть следующим образом: (обратите внимание, что я выбираю только идентификатор сообщения root, поскольку это все Вы просили, если вам нужно больше столбцов, включите их в select)

select  msg_id
from    table_x
where   connect_by_isleaf = 1  -- keep just the root row (leaf in this traversal)
start   with id = :input_id    -- to give the starting node
connect by prior parent_id = id
;
0 голосов
/ 23 апреля 2020

Вы можете использовать рекурсивный запрос:

with cte (id, msg_id, parent_id) as (
    select id, msg_id, parent_id, from mytable where id = ?
    union all
    select t.id, t.msg_id, t.parent_id
    from mytable t
    inner join cte c on c.parent_id = t.id
)
select * from cte where parent_id is null
...