PSQL - перебрать таблицу и вернуть результаты в виде таблицы - PullRequest
0 голосов
/ 19 апреля 2020


Работа с таблицей со столбцами
some_id , some_parent_id , some_param .

Мне нужно создать процедура или функция, которые принимают some_id в качестве входных данных и ищут свою родительскую строку.
Когда родительская строка найдена, она снова будет искать родительскую строку этой строки ... и так далее ... до тех пор, пока родительская строка не станет нулевой.
Функция должна возвращать все записи, найденные во время итерации.

enter image description here

Так что в этом случае, если функция вызывается со значением 3, она возвращает строки 2 и 1 и остановка там, потому что some_parent_id равен нулю

Это моя попытка сохранить результаты во временной таблице, но все, что я получаю, это NULL. Чего мне не хватает?

CREATE OR REPLACE FUNCTION my_function(
    input_id int) 
RETURNS TABLE(
    r_id int,
    r_parent_id int,
    r_param int,
) AS $$
    DECLARE
        temp_table record;
        search_id int;
    begin
        search_id := input_id;
        for temp_table in (
            select some_id, some_parent_id, some_param FROM mytable where some_id = search_id)
        loop 
            search_id := temp_table.some_parent_id;
            return next;    
        end loop;
        return;
    END;
$$ LANGUAGE plpgsql;

select * from  my_function (3754);

Я ценю любую помощь

1 Ответ

1 голос
/ 19 апреля 2020

Одна опция использует рекурсивный запрос вместо al oop:

with recursive cte as (
    select some_id, some_parent_id, some_param 
    from mytable 
    where some_id = input_id 
    union all
    select t.some_id, t.some_parent_id, t.some_param
    from mytable t
    inner join cte c on t.some_id = c.some_parent_id
)
select * from cte

Вы можете использовать этот запрос в своей функции следующим образом:

create or replace function my_function(input_id int) 
returns table(
    r_id int,
    r_parent_id int,
    r_param text
) as $$
with recursive cte as (
    select some_id, some_parent_id, some_param 
    from mytable 
    where some_id = input_id 
    union all
    select t.some_id, t.some_parent_id, t.some_param
    from mytable t
    inner join cte c on t.some_id = c.some_parent_id
)
select * from cte
$$
language sql;

Демонстрация на DB Fiddle с вашими примерами данных:

select * from my_function(2);

| r_id | r_parent_id | r_param |
| ---- | ----------- | ------- |
| 2    | 1           | value2  |
| 1    |             | value1  |
...