【问题标题】:How to split a type into multiple columns in Postgres?如何在 Postgres 中将一个类型拆分为多个列?
【发布时间】:2011-02-01 18:11:31
【问题描述】:

我有以下代码从 pl/python 返回多个值:

CREATE TYPE named_value AS (
  name   text,
  value  integer
);
CREATE or replace FUNCTION make_pair (name text, value integer)
  RETURNS named_value
AS $$
  return [ name, value ]
$$ LANGUAGE plpythonu;

select make_pair('egg', 4) as column;

输出是:

column
(egg,4)

我想要做的是将输出分成两个单独的列。像这样:

column, column2
egg, 4

我该怎么做?谷歌搜索 1 小时让我无处可去。所以我希望我会在最后添加一些搜索关键字: 多个返回值 多个结果 多列 unnest list unnest set

【问题讨论】:

    标签: postgresql plpgsql plperl


    【解决方案1】:

    是的,这个语法有点古怪,需要额外的括号:

    select (make_pair('egg', 4)).name
    

    要在只调用一次函数的同时从输出中获取多个组件,您可以使用子选择:

    select (x.column).name, (x.column).value from (select make_pair('egg', 4) as column) x;
    

    【讨论】:

    • 您的代码有效,但我真的需要一个子选择来执行此操作吗?我与 make_pair('egg', 4).name 如此接近,但这不起作用。
    • 你可以说select (make_pair('egg', 4)).name,例如。如果您想要两个组件但只执行一次功能,我认为您需要子选择。我会更新答案。
    • 不必多次执行该函数绝对是一个目标。
    • 我已经用工作代码添加了我自己的答案,以避免必须运行该函数两次,同时避免子查询。当你引导我时,我仍然会接受你的回答。
    【解决方案2】:
    SELECT * FROM make_pair('egg', 4);
    

    以及一些变体:

     SELECT name, value FROM make_pair('egg', 4) AS x;
    
    
     SELECT a, b FROM make_pair('egg', 4) AS x(a,b);
    

    【讨论】:

    • 这是一个非常优雅的解决方案,但我不知道如何在需要对表中的每一行运行该函数的情况下使用它。性能对我来说也很重要。
    【解决方案3】:

    我找到的一个解决方案是使用 join:

    create table tmp (a int, b int, c int);
    insert into tmp (a,b,c) values (1,2,3), (3,4,5), (5,12,13);
    create type ispyth3 as (is_it boolean, perimeter int);
    create function check_it(int, int, int) returns ispyth3 as $$
        begin
            return ($1*$1 + $2*$2 = $3*$3, $1+$2+$3);
        end
    $$ language plpgsql;
    select * from tmp join check_it(a,b,c) on 1=1;
    

    这会返回:

     a | b  | c  | is_it | perimeter 
    ---+----+----+-------+-----------
     1 |  2 |  3 | f     |         6
     3 |  4 |  5 | t     |        12
     5 | 12 | 13 | t     |        30
    (3 rows)
    

    【讨论】:

    • 另一种表达交叉连接的方式是使用JOIN CHECK_it(a,b,c) ON TRUE 或简单地使用CROSS JOIN
    【解决方案4】:

    以下是工作代码,以避免必须运行该函数两次,同时避免子查询。

    CREATE TYPE named_value AS (
      name   text,
      value  integer
    );
    
    CREATE or replace FUNCTION setcustomvariable(variablename text, variablevalue named_value)
      RETURNS named_value
    AS $$
      GD[variablename] = variablevalue
      return variablevalue
    $$ LANGUAGE plpythonu;
    
    CREATE or replace FUNCTION getcustomvariable(variablename text)
      RETURNS named_value
    AS $$
      return GD[variablename]
    $$ LANGUAGE plpythonu;
    
    CREATE or replace FUNCTION make_pair (name text, value integer)
      RETURNS named_value
    AS $$
      return [ name, value ]
    $$ LANGUAGE plpythonu;
    
    select setcustomvariable('result', make_pair('egg', 4)), (getcustomvariable('result')).name, (getcustomvariable('result')).value
    

    【讨论】:

      猜你喜欢
      • 2020-05-27
      • 1970-01-01
      • 2015-06-07
      • 2020-02-10
      • 1970-01-01
      • 2011-05-05
      • 2021-03-27
      • 1970-01-01
      相关资源
      最近更新 更多