3

我在 Oracle 中有以下查询:

SELECT to_number(a.v_VALUE), b.v_VALUE
       FROM TABLE(inv_fn_splitondelimiter('12;5;25;10',';')) a
       JOIN TABLE(inv_fn_splitondelimiter('10;20;;', ';')) b
         ON a.v_idx = b.v_idx

这给了我这样的结果:

在此处输入图像描述

我想将查询转换为 Postgres。我试过这样的查询:

SELECT UNNEST(String_To_Array('10;20;',';'))

我也试过:

SELECT a,b
       FROM (select  UNNEST(String_To_Array('12;5;25;10;2',';'))) a
       LEFT JOIN (select  UNNEST(String_To_Array('12;5;25;10',';'))) b
         ON a = b

但是没有得到正确的结果。
我不知道如何编写完全等同于 Oracle 版本的查询。任何人?

4

2 回答 2

7

从 Postgres 9.4开始,您可以使用unnest()多个数组来并行取消嵌套它们:

SELECT *
FROM   unnest('{12,5,25,10,2}'::int[]
            , '{10,20}'       ::int[]) AS t(col1, col2);

就这样。NULL右侧缺失元素的值会自动填充。

如果参数以字符串形式提供,请先转换string_to_array()。像:

SELECT *
FROM   unnest(string_to_array('12;5;25;10', ';')
            , string_to_array('10;20'     , ';')) AS t(col1, col2);

更多详细信息和旧版本的替代解决方案:

于 2015-02-13T07:57:17.843 回答
3

表达式select a中的a不是列,而是表别名。因此,表达式选择了一个完整的行元组(尽管只有一列),而不是一列。

您需要为派生表定义正确的列别名。还建议仅在 from 子句中使用集合返回函数,而不是在选择列表中。

如果您不在 9.4 上,则需要使用窗口函数生成“索引”。如果您使用的是 9.4,那么 Erwin 的答案要好得多。

SELECT a.v_value, b.v_value
FROM (
   select row_number() over () as idx,  -- generate an index for each element
          i as v_value
   from UNNEST(String_To_Array('12;5;25;10;2',';')) i
) as a 
  JOIN (
     select row_number() over() as idx, 
            i as v_value
     from UNNEST(String_To_Array('10;20;;',';')) i
  ) as b 
  ON a.idx = b.idx;

9.4 中的另一种方法是使用with ordinality选项生成行索引,以防您确实需要索引值:

select a.v_value, b.v_value
from regexp_split_to_table('12;5;25;10;2',';') with ordinality as a(v_value, idx)
  left join regexp_split_to_table('10;20;;',';') with ordinality as b(v_value, idx) 
    on a.idx = b.idx
于 2015-02-13T07:49:08.357 回答