Postgres执行查询以选择数组索引

时间:2014-03-19 21:46:43

标签: sql postgresql

如果我在不同列上的相同索引处具有所需值,那么如何执行返回行的查询?例如,以下是一些代码:

select id_reg, a1, a2 from lb_reg_teste2;
 id_reg |        a1        |     a2   
--------+------------------+-------------
      1 | {10,10,20,20,10} | {3,2,4,3,6}
(1 row)

查询可能会像:

select id_reg from lb_reg_teste2 where idx(a1, '20') = idx(a2, '3');
# Should return id_reg = 1

我找到了这个脚本,但它只返回数组中第一次出现的值。对于这种情况,我需要所有事件。

CREATE OR REPLACE FUNCTION idx(anyarray, anyelement)
  RETURNS int AS
$$
  SELECT i FROM (
     SELECT generate_series(array_lower($1,1),array_upper($1,1))
  ) g(i)
  WHERE $1[i] = $2
  LIMIT 1;
$$ LANGUAGE sql IMMUTABLE;

1 个答案:

答案 0 :(得分:0)

您可以从数组中提取值及其索引,然后过滤掉结果。

如果数组具有相同数量的元素,请考虑以下查询:

SELECT id_reg,
       generate_subscripts(a1,1) as idx1,
       unnest(a1) as val1,
       generate_subscripts(a2,1) as idx2,
       unnest(a2) as val2
  FROM lb_reg_teste2

使用问题的样本值,这将产生以下结果:

 id_reg | idx1 | val1 | idx2 | val2 
--------+------+------+------+------
      1 |    1 |   10 |    1 |    3
      1 |    2 |   10 |    2 |    2
      1 |    3 |   20 |    3 |    4
      1 |    4 |   20 |    4 |    3
      1 |    5 |   10 |    5 |    6

然后将其用作子查询并添加WHERE子句以根据需要进行过滤。 对于203作为要在同一索引处查找的值的示例:

SELECT DISTINCT id_reg FROM
   ( SELECT id_reg,
           generate_subscripts(a1,1) as idx1,
           unnest(a1) as val1,
           generate_subscripts(a2,1) as idx2,
           unnest(a2) as val2
      FROM lb_reg_teste2 ) s
    WHERE idx1=idx2 AND val1=20 AND val2=3;

如果a1a2的元素数量不同,则上面的子查询将生成一个笛卡尔积(NxMNM为数组大小),所以这将效率较低,但仍然会产生正确的结果,只要我理解你的期望。

在这种情况下,一个变体是用每个数组的(values,indices)生成两个不同的子查询,并通过索引的相等性将它们连接起来。