将SELECT结果作为参数传递给postgreSQL函数

31

我有一个名为“UserState”的表格,包括以下字段:

  • id
  • userid
  • ctime
  • state
  • endtime

我有一个简单的查询:

SELECT userid FROM "UserState" WHERE ctime>'2014-07-14'::timestamp

我有一个 plpgsql 函数,需要以此查询的结果作为参数:

get_timeinstate(SELECT userid FROM "UserState" WHERE ctime>'2014-07-14'::timestamp);

如何正确创建函数以将查询结果作为参数传递?需要理解的是,该函数返回另一个 SQL 结果,我需要在其中使用“IN”条件:

$func$
BEGIN
 RETURN QUERY
 SELECT 
...myanotherquery...
 WHERE "UserState".userid IN (HERE I NEED TO INSERT MY QUERY RESULT)
END;
$func$

https://dev59.com/T2Ml5IYBdhLWcg3wqIhh - Ilesh Patel
2
看起来你正在寻找 LATERAL:http://www.postgresql.org/docs/current/static/sql-select.html - user330315
4个回答

20

将返回的用户ID集合作为数组传递。 创建一个接受整数数组的函数。

create function get_timeinstate (
    user_id_set integer[],
    another_param...

然后调用它,传递由array_agg生成的数组

get_timeinstate(
    (
        select array_agg(userid)
        from "UserState"
        where ctime>'2014-07-14'::timestamp
    ),
    another_param
);

在函数内部:

where "UserState".userid = any (user_id_set)

顺便提一下,如果你正在使用plpgsql,你可以将查询放在函数内部,然后只传递日期:

create function get_timeinstate (
    p_ctime timestamp,
    another_param...
$func$
declare
    user_id_set integer[] := (
        select array_agg(userid)
        from "UserState"
        where ctime > p_ctime
    );
begin
    return query
    select 
    ...myanotherquery...
    where "UserState".userid = any (user_id_set)
end;
$func$

不行,因为我有大约30个函数和只有一个查询,必须将其作为参数传递给所有函数。 将查询结果作为参数传递,我只能执行一次。并且在函数中使用此查询,我将执行30次。我需要更少的时间消耗。 - user3824666
@user3824666 这些函数会立即使用吗?如果不是,您将传递旧数据(作为整数数组 userid :: int [],这是解决方案)。或者,传递旧数据是否可以接受?否则,如果目的是_不要重复自己_,则将查询本身作为一个函数并通过参数传递 date - Clodoaldo Neto
这些函数将被立即使用,但我不知道如何处理数组。我无法在SELECT语句中使用IN运算符,但我需要它。 我无法相信,无法将列作为参数传递。 - user3824666
@user3824666 可以传递一个列值。除了通过数组形式,传递一组值是不可能的。我会发帖说明如何做到这一点。 - Clodoaldo Neto
好的,这就是我需要的。谢谢! - user3824666
1
我在这里缺少什么?我的答案有什么问题? - MrR

18

只需用圆括号括起来:

get_timeinstate(
  (
    SELECT userid FROM "UserState" WHERE ctime>'2014-07-14'::timestamp
  )
);

3
最佳答案显然,但您能解释一下为什么那个额外的括号会产生如此巨大的影响吗? - fwiw
1
额外的括号将整个子查询封装起来,确保子查询的结果被视为一个单一实体,无论它返回单行还是多行。如果没有这些括号,SQL引擎可能会将SELECT语句解释为get_timeinstate()函数的多个不同输入。额外的括号层次为SQL引擎提供了清晰度,明确说明子查询结果的整体应被视为函数的单一输入。 - MrR

-1
在我的情况下,我使用以下方式来传递SELECT语句的结果。
SELECT get_timeinstate(userid) FROM "UserState" WHERE ctime>'2014-07-14'::timestamp

-2
将 SELECT 放入圆括号中,或使用数组构造函数(在这种情况下可以更改设置返回的选择中的索引) 例如:
with p as
(
    select id, xyz geometry from insar1.point
)
, extent as
(
    select st_extent(st_force2d(geometry)) geometry from p
)
INSERT INTO insar1.grid (geometry)
SELECT (
    ST_Dump(
      makegrid_2d(
        --maybe you need limit 1
        (SELECT e.geometry from extent e), --just use braces
        --this works too:
        --(ARRAY(SELECT e.geometry from extent e))[1],
         100,
         100
       )
    )
  ) .geom geometry

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接