在Postgres查询中保留数组成员顺序

问题描述 投票:1回答:1

我想知道在Postgres中发出select查询时如何保留/利用数组元素的顺序。 (如果相关,则数组是多维的。)

例如,给出以下数据:

 id |             points
----+---------------------------------
  1 | {{1,3},{7,11},{99,101},{0,1}}
  2 | {{99,101},{7,11},{0,1},{77,22}}

我想知道如何编写一个查找points行的查询:

  • 包含子阵列{{7, 11}, {99, 101}}
  • 但不是{{99, 101},{7, 11}}

我尝试使用各种数组运算符(@>&&),使用intarray模块添加索引等,但还没有找到可行的解决方案。

sql arrays postgresql postgresql-9.6
1个回答
1
投票

能够“以1维度排除阵列”并使用incomarison的结果集,使用Pavel Stěhule建议function

t=# with c(i,p) as (values(1,'{{1,3},{7,11},{99,101},{0,1}}'::int[][]),(2,'{{99,101},{7,11},{0,1},{77,22}}'))
, p as (select *,a,case when e = '{7, 11}' and lead(e) over (partition by i order by o) = '{99, 101}' and o = lead(o) over (partition by i order by o) -1 then true end from c, reduce_dim(p) with ordinality as a (e,o))
select * from p;
 i |                p                |    e     | o |       a        | case
---+---------------------------------+----------+---+----------------+------
 1 | {{1,3},{7,11},{99,101},{0,1}}   | {1,3}    | 1 | ("{1,3}",1)    |
 1 | {{1,3},{7,11},{99,101},{0,1}}   | {7,11}   | 2 | ("{7,11}",2)   | t
 1 | {{1,3},{7,11},{99,101},{0,1}}   | {99,101} | 3 | ("{99,101}",3) |
 1 | {{1,3},{7,11},{99,101},{0,1}}   | {0,1}    | 4 | ("{0,1}",4)    |
 2 | {{99,101},{7,11},{0,1},{77,22}} | {99,101} | 1 | ("{99,101}",1) |
 2 | {{99,101},{7,11},{0,1},{77,22}} | {7,11}   | 2 | ("{7,11}",2)   |
 2 | {{99,101},{7,11},{0,1},{77,22}} | {0,1}    | 3 | ("{0,1}",3)    |
 2 | {{99,101},{7,11},{0,1},{77,22}} | {77,22}  | 4 | ("{77,22}",4)  |
(8 rows)

现在,你看到逻辑,完整的where

t=# with c(i,p) as (values(1,'{{1,3},{7,11},{99,101},{0,1}}'::int[][]),(2,'{{99,101},{7,11},{0,1},{77,22}}'))
, p as (select *,a,case when e = '{7, 11}' and lead(e) over (partition by i order by o) = '{99, 101}' and o = lead(o) over (partition by i order by o) -1 then true end from c, reduce_dim(p) with ordinality as a (e,o))
select i,p from p where "case";
 i |               p
---+-------------------------------
 1 | {{1,3},{7,11},{99,101},{0,1}}
(1 row)

更不用说在顺序数组对的情况下,您可以将其强制转换为文本并使用like运算符:

t=# with c(i,p) as (values(1,'{{1,3},{7,11},{99,101},{0,1}}'::int[][]),(2,'{{99,101},{7,11},{0,1},{77,22}}'))
select * from c where p::text like '%{7,11},{99,101}%';
 i |               p
---+-------------------------------
 1 | {{1,3},{7,11},{99,101},{0,1}}
(1 row)
© www.soinside.com 2019 - 2024. All rights reserved.