将函数返回的数组转换为列

wtlkbnrh  于 2022-10-15  发布在  PostgreSQL
关注(0)|答案(4)|浏览(152)

我在PostgreSQL(PLPGSQL)中有一个函数,它返回一个包含两个元素的数组。当我运行调用该函数的SELECT语句时,我得到一个包含数组的列(不出所料):

{1, 2}

我真正想做的是将这些元素提取为它们自己的列:

[ 1 | 2 ]

我发现我可以做到:

SELECT (MyFunction())[1], (MyFunction())[2]

但这会调用该函数两次,因此运行时间增加了一倍(该函数非常耗时)。有没有更好的办法来处理这件事?
这是我所拥有的近乎完美的复制品:

SELECT table1.a, table1.b, table1.c, (MyFunction(table1.a, table1.b, table1.c))[1],
(MyFunction(table1.a, table1.b, table1.c))[2]
FROM table1
INNER JOIN table2 using(b)
WHERE ... GROUP BY table1.a, table1.b, table1.c;

同样,这将从数组中生成两列,但我的函数被调用了两次,这使我的运行时间加倍。

iugsix8n

iugsix8n1#

您可以使用小选吗?

postgres=# select ar[1], ar[2] from (select string_to_array('a b c', ' ') ar) as sq;
 ar | ar 
----+----
 a  | b
(1 row)

这仍然需要您显式地提取每一列(就像您已经做的那样)。如果数组中的元素多于提取的元素,则它们将丢失,如果元素较少,则缺少的列将仅为NULL
编辑:我想我应该将整个内容 Package 在一个子选择中;内部的子选择生成所需的,而外部的选择将内部查询投影到所需的中:

SELECT subquery1.a, subquery1.b, subquery1.c, 
    myfunction_result[1], myfunction_result[2] 
FROM ( SELECT table1.a, table1.b, table1.c,
              MyFunction(table1.a, table1.b, table1.c) as myfunction_result
       FROM table1 INNER JOIN table2 using(b) 
       WHERE ... GROUP BY table1.a, table1.b, table1.c
) AS subquery1;

内部选择和外部选择将正确关联table1引用。

hfyxw5xn

hfyxw5xn2#

select data[1] as id, data[2] as value from (SELECT 
string_to_array(rs,':') as data from unnest(string_to_array('1:234,2:400',',')) as rs) as foo

这将导致:

id|Value
--------
1 | 234
2 | 400
33qvvth1

33qvvth13#

你不能这么做。例如,单个阵列列可以具有具有三个元素的一个阵列和具有五个元素的另一个阵列。如果您试图将这些数组展开为单独的列,则结果集中会出现两行列数不同的结果,这是不允许的。
可用的最接近的是unnest
将数组展开为一组行
但这为您提供了行,而不是您想要的列。

fslejnso

fslejnso4#

如果您尝试从FUNCTION返回TABLE,我发现子选择对我不起作用(当在FUNCTION中与RETURN QUERY一起使用时,SingleNegationElimination's answer返回单列),所以我不得不使用WITH,如下所示:

CREATE
OR REPLACE FUNCTION STRING_TO_TABLE(
  IN P_STRING text, 
  IN P_DELIMITER text DEFAULT ' '
) RETURNS TABLE (
    FIRST text, 
    SECOND text
) LANGUAGE plpgsql AS $$

BEGIN

  RETURN QUERY
    WITH SQ AS (
      SELECT STRING_TO_ARRAY(P_STRING, P_DELIMITER) A
    )
    SELECT 
      A[1] AS FIRST,
      A[2] AS SECOND
    FROM SQ;

END $$;

然后允许您将SELECT...INTO与如下函数一起使用:

SELECT
  FIRST,
  SECOND
FROM
  STRING_TO_TABLE('first second')
INTO
  P_FIRST,
  P_SECOND;

相关问题