在函数内的另一个查询中使用从函数返回的值

问题描述 投票:0回答:1

我正在尝试构造一个 Postgres 函数,它可以使用 where 子句中另一个 select 的结果。以下效果很好

create or replace function get_film_count(a varchar[], v varchar[])
 RETURNS Table(costs decimal, id varchar, in_node varchar[], out_node varchar[], cycle BOOLEAN,visted_list varchar[])
 language plpgsql
 as
 '
 begin
   RETURN QUERY  SELECT  edg.costs, edg.id, ARRAY[edg.in_node], ARRAY[edg.out_node], edg.in_node = ANY(v), v || ARRAY[edg.in_node]
        FROM edges edg where edg.in_node=ANY(a) AND edg.in_node != ANY(v)
        union all 
            SELECT  edg.costs, edg.id, ARRAY[edg.in_node], ARRAY[edg.out_node], edg.in_node = ANY(v), v || ARRAY[edg.in_node]
        FROM edges edg where edg.in_node=ANY(SELECT edg.out_node
        FROM edges edg where edg.in_node=ANY(a) AND edg.in_node != ANY(v));
 end;
';
select * from get_film_count(ARRAY['a'], ARRAY['']);

但是我正在寻找类似于以下内容的东西

create or replace function get_film_count(a varchar[], v varchar[])
 RETURNS Table(costs decimal, id varchar, in_node varchar[], out_node varchar[], cycle BOOLEAN,visted_list varchar[])
 language plpgsql
 as
 '
 begin
   list_of_out_nodes= select out_node from (get_film_count(ARRAY(edg.out_node), v || ARRAY[edg.in_node]))
   RETURN QUERY  SELECT  edg.costs, edg.id, ARRAY[edg.in_node], ARRAY[edg.out_node], edg.in_node = ANY(v), v || ARRAY[edg.in_node]
        FROM edges edg where edg.in_node=ANY(a) AND edg.in_node != ANY(v)
        union all 
            SELECT  edg.costs, edg.id, ARRAY[edg.in_node], ARRAY[edg.out_node], edg.in_node = ANY(v), v || ARRAY[edg.in_node]
        FROM edges edg where edg.in_node=ANY(list_of_out_nodes);
 end;
';
select * from get_film_count(ARRAY['a'], ARRAY['']);

所以基本上我正在寻找使用递归调用函数来代替并获取列的值作为列表并将其输入返回查询中 注意:我知道 Postgres 的递归功能,但我专门寻找这种方法

sql postgresql plpgsql postgresql-9.5
1个回答
0
投票

我相信您将需要一个 CTE 来允许第一个函数调用返回的集合在第二个调用中可用,如下所示:

CREATE OR REPLACE FUNCTION get_film_count(a varchar[], v varchar[])
RETURNS TABLE(costs decimal, id varchar, in_node varchar[], out_node varchar[], cycle BOOLEAN, visited_list varchar[])
LANGUAGE plpgsql
AS $$
DECLARE
    list_of_out_nodes varchar[];
BEGIN
    RETURN QUERY  
        WITH recursive_nodes AS (
            SELECT edg.out_node 
            FROM get_film_count(ARRAY[edg.out_node], v || ARRAY[edg.in_node])
        )
        SELECT edg.costs, edg.id, ARRAY[edg.in_node], ARRAY[edg.out_node], edg.in_node = ANY(v), v || ARRAY[edg.in_node]
        FROM edges edg 
        WHERE edg.in_node = ANY(a) AND edg.in_node != ANY(v)
        UNION ALL 
        SELECT edg.costs, edg.id, ARRAY[edg.in_node], ARRAY[edg.out_node], edg.in_node = ANY(v), v || ARRAY[edg.in_node]
        FROM edges edg 
        WHERE edg.in_node = ANY((SELECT * FROM recursive_nodes));
END; $$;

不过,我不能说我对这个概念非常热衷。看起来过于“聪明”,可能是一个支持问题(这只是直觉!)。

© www.soinside.com 2019 - 2024. All rights reserved.