查询 Postgres JSONB 列中的多个数组元素

Query for multiple array elements in Postgres JSONB column

我有一个 table mydata jsonb 列,其中包含一个整数数组。

create table mydata
(
    name varchar,
    data jsonb
);

这里是一些测试数据:

insert into mydata (name, data)
VALUES
('hello1', '[1]'),
('hello12', '[1,2]'),
('hello2', '[2]'),
('hello23', '[2,3]')
;

我现在想在 table 中查询“数据”中包含 2 或 3(或两者)的元素。 除了:

之外还有更好的语法吗?
select * from mydata where (data @> '2' or data @> '3');

因为我当然可以查询 2 个以上的选项。我会假设我能够做这样的子查询(不工作,就像暗示我想要实现的那样):


create table other ( id bigserial , text varchar);
insert into other (id, text) values (1, 'x'), (2, 'y'), (3, 'y'), (4, 'z');

我现在想做的是,从 mydata 中获取所有数据,其中数据引用了 other_table

select * from mydata where (data @> IN (select distinct id from other_table where text='y'));

非常感谢, 弗里茨

step-by-step demo:db<>fiddle

SELECT DISTINCT                             -- 3
    name,
    data
FROM mydata,
   jsonb_array_elements_text(data) elems    -- 1
WHERE value::int IN (
    SELECT id FROM other WHERE "text" = 'y' -- 2
)
  1. 将所有数组元素提取到自己的记录中
  2. 过滤之前的元素是否是子查询的元素
  3. 因为此过滤器可以 return 两次相同的记录(如果原始数据匹配 23),DISTINCT 确保 return独特的记录。

如果 ID 来自不同的 table,您可以这样做:

select *
from mydata m
where exists (select *
              from other o
              where o.id in (select v::int 
                             from jsonb_array_elements_text(m.data) as x(v)))

对于 Postgres 12 或更高版本,您可以使用

select *
from mydata m
where exists (select *
              from other o
              where jsonb_path_exists(m.data, '$[*] ? (@ == $id)', jsonb_build_object('id', o.id)))

不确定哪个会更快。