PostgreSQL使用位置数组从数组访问多个元素

时间:2018-05-13 18:21:58

标签: arrays postgresql

我想知道PostgreSQL中是否有可能通过使用另一个指示元素位置的数组来从数组的多个元素输出数组。

确切地说:

array1 = [1,2,1]        
array_positions(array1,'1') = {1,3}
array2 = ['hello', 'bye', 'hello']

期望的结果:

array2[array_positions(array1,'1')] = {'hello', 'hello'}

我收到ERROR: array subscript must have type integer 有什么建议吗?

2 个答案:

答案 0 :(得分:2)

这可能会或可能不会太复杂而无法发挥作用,但它确实证明了这一点:

SELECT vals.*
FROM (
  VALUES(array['hello', 'bye', 'hello'])
) AS t (arr)
JOIN lateral unnest(t.arr) WITH ORDINALITY AS vals(element, idx) ON TRUE
WHERE vals.idx = ANY(array_positions(array[1,2,1], 1));

答案 1 :(得分:1)

缺少的部分是一个函数/运算符,它从指定的位置返回数组元素(我真的很惊讶它在发布中不存在,希望它将被修复)。让我们创建它们:

create or replace function array_from_positions(anyarray, int[]) returns anyarray
  immutable language sql 
as $$
  select array_agg(a.x order by b.i)
  from
    unnest($1) with ordinality as a(x,i)
      right join unnest($2) with ordinality as b(x,i) on (a.i=b.x)
$$;

测试:

select
  array_from_positions('{a,b,c,d}'::text[], '{2,1,10}'),
  array_from_positions('{1,2,3,4}'::int[], '{2,1,10}');
┌──────────────────────┬──────────────────────┐
│ array_from_positions │ array_from_positions │
├──────────────────────┼──────────────────────┤
│ {b,a,NULL}           │ {2,1,NULL}           │
└──────────────────────┴──────────────────────┘
create operator ## (
  procedure = array_from_positions,
  leftarg = anyarray,
  rightarg = int[] );

测试:

select
  '{a,b,c,d}'::text[] ## '{2,1,10}',
  '{1,2,3,4}'::int[] ## '{2,1,10}';
┌────────────┬────────────┐
│  ?column?  │  ?column?  │
├────────────┼────────────┤
│ {b,a,NULL} │ {2,1,NULL} │
└────────────┴────────────┘

最后测试你的例子:

with your_table(array1,array2) as (values
  ('{1,2,1}'::int[], '{hello,bye,hello}'::text[]))
select array2 ## array_positions(array1, 1) from your_table;
┌───────────────┐
│   ?column?    │
├───────────────┤
│ {hello,hello} │
└───────────────┘