Sql 以jsonb数组中的特定对象为目标

Sql 以jsonb数组中的特定对象为目标,sql,json,postgresql,jsonb,Sql,Json,Postgresql,Jsonb,我需要从表中选择符合特定条件的行,这涉及jsonb对象字段比较 在下面的示例中,我只想获取值在数组中的对象指定的最小/最大范围内的行:对于任何给定行,如果其数组中的任何对象包含使用最小/最大比较的值,我需要该行 CREATE TABLE test_table ( id serial, value int, array_of_objects jsonb[] ); INSERT INTO test_table (value, array_of_objects) VALUES (

我需要从表中选择符合特定条件的行,这涉及jsonb对象字段比较

在下面的示例中,我只想获取值在数组中的对象指定的最小/最大范围内的行:对于任何给定行,如果其数组中的任何对象包含使用最小/最大比较的值,我需要该行

CREATE TABLE test_table (
  id serial,
  value int,
  array_of_objects jsonb[]
);

INSERT INTO
  test_table (value, array_of_objects)
VALUES
  (8, ARRAY ['{"min":5,"max":15}', '{"min":4,"max":18}']::jsonb[]),
  (6, ARRAY ['{"min":12,"max":18}', '{"min":19,"max":22}']::jsonb[]),
  (22, ARRAY ['{"min":16,"max":18}', '{"min":34,"max":47}']::jsonb[]);

因此,对于给定的示例,我只得到值为8和22的行。

如果您想要原始列:

t=# with a as (select unnest(array_of_objects) j,* from test_table)
select distinct id,value, array_of_objects
from a
where (j->>'min')::int < value and (j->>'max')::int > value;
 id | value |                     array_of_objects
----+-------+-----------------------------------------------------------
  1 |     8 | {"{\"max\": 15, \"min\": 5}","{\"max\": 18, \"min\": 4}"}
(1 row)
这里解释了为什么值22没有进入数组\u的\u对象[1]->>max小于22:

Time: 0.441 ms
t=# with a as (select unnest(array_of_objects) j,* from test_table)
select distinct id,value,j
from a
where (j->>'min')::int < value and (j->>'max')::int > value;
 id | value |           j
----+-------+-----------------------
  1 |     8 | {"max": 18, "min": 4}
  1 |     8 | {"max": 15, "min": 5}
(2 rows)

Time: 0.390 ms

如果需要原始列,请执行以下操作:

t=# with a as (select unnest(array_of_objects) j,* from test_table)
select distinct id,value, array_of_objects
from a
where (j->>'min')::int < value and (j->>'max')::int > value;
 id | value |                     array_of_objects
----+-------+-----------------------------------------------------------
  1 |     8 | {"{\"max\": 15, \"min\": 5}","{\"max\": 18, \"min\": 4}"}
(1 row)
这里解释了为什么值22没有进入数组\u的\u对象[1]->>max小于22:

Time: 0.441 ms
t=# with a as (select unnest(array_of_objects) j,* from test_table)
select distinct id,value,j
from a
where (j->>'min')::int < value and (j->>'max')::int > value;
 id | value |           j
----+-------+-----------------------
  1 |     8 | {"max": 18, "min": 4}
  1 |     8 | {"max": 15, "min": 5}
(2 rows)

Time: 0.390 ms

可以避免在PostgreSQL 10之后的某个时间使用unnest

PostgreSQL CommitTest实现了大量JSON相关函数,作为最新标准的一部分进行了标准化:

下面是一个例子:

CREATE TABLE my_table (
  title VARCHAR,
  number INTEGER,
  my_array JSONB
);

INSERT INTO my_table (title, number, my_array) VALUES
  ('not expected', 6, '[{"min": 1, "max": 5}, {"min": 7, "max": 10}]'::JSONB),
  ('expected', 7, '[{"min": 1, "max": 5}, {"min": 7, "max": 10}]'::JSONB);

SELECT *
  FROM my_table
 WHERE JSON_EXISTS(my_array, '$[*] ? (@.min < $x && $x <= @.max)' PASSING number AS x);

可以避免在PostgreSQL 10之后的某个时间使用unnest

PostgreSQL CommitTest实现了大量JSON相关函数,作为最新标准的一部分进行了标准化:

下面是一个例子:

CREATE TABLE my_table (
  title VARCHAR,
  number INTEGER,
  my_array JSONB
);

INSERT INTO my_table (title, number, my_array) VALUES
  ('not expected', 6, '[{"min": 1, "max": 5}, {"min": 7, "max": 10}]'::JSONB),
  ('expected', 7, '[{"min": 1, "max": 5}, {"min": 7, "max": 10}]'::JSONB);

SELECT *
  FROM my_table
 WHERE JSON_EXISTS(my_array, '$[*] ? (@.min < $x && $x <= @.max)' PASSING number AS x);

mx:18小于22,那么为什么这里也是22?你有一个条件可以应用于数组的所有元素?。看看我的答案-如果我对value列的数组的所有元素应用min