PSQL - 迭代 table 和 return 结果为 table

PSQL - Iterate over table and return results as table


使用列
处理 table some_id, some_parent_id, some_param.

我需要创建一个接受 some_id 作为输入并搜索其父行的过程或函数。
找到父行后,它将再次搜索该行的父行……依此类推……直到父行为空。
函数应该 returns 在迭代期间找到的所有条目。

因此,在这种情况下,如果使用值 3 调用函数,它将 return 第 2 行和第 1 行并停在那里,因为 some_parent_id 为空

这是我在临时 table 中存储结果的尝试,但我得到的只是 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);

感谢任何帮助

一个选项使用递归查询而不是循环:

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;

Demo on DB Fiddle 使用您的示例数据:

select * from my_function(2);

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