如何从postgres json字段中选择包含某些值的所有记录containsig一个数组

时间:2019-08-19 21:46:00

标签: postgresql

我有tableA,其中包含一个json字段data。字段data的抽象示例:

{"sequence": [123,456,789]}
{"sequence": [456,789]}
{"sequence": [789, 12]}

更新:在sqlfiddle中添加了一些示例数据-> http://sqlfiddle.com/#!17/62475/24

使用

select * from tableA where (data->'sequence') @> '[456]';

我能够选择所有包含456的记录:

{"sequence": [123,456,789]}
{"sequence": [456,789]}

我正在努力选择所有包含123456的记录。这可能吗?

123456包含为子查询,如:

select * from tableA where (data->'sequence') in (select data_id from tableB);

1 个答案:

答案 0 :(得分:1)

使用ANY来测试jsonb数组是否包含正确值的 any ,可以使用您的sqlfiddle示例来作为数组或子查询。

SELECT *
FROM tableA
WHERE (data->'sequence') @> ANY(SELECT (data_id::TEXT)::JSONB FROM tableB)

您还可以传递一个数组文字,在这种情况下,它需要一个JSONB值数组,即@>的右侧可以用文字ANY('{123,456}'::JSONB[])

代替

或者,使用&&测试数组重叠。首先需要将JSON / JSONB数组转换为本地数组

SELECT tableA.*
FROM tableA 
JOIN LATERAL (
  SELECT ARRAY_AGG(v::INT) y 
  FROM JSONB_ARRAY_ELEMENTS_TEXT(data->'sequence') v
) x ON TRUE
WHERE x.y && '{123, 456}'

您还可以用返回整数数组的子查询替换数组文字'{123, 456}',例如(SELECT ARRAY_AGG(data_id) FROM tableB)

另一种选择是在您的where子句中使用或

select *
from tableA 
where (data->'sequence') @> '[456]'
   or (data->'sequence') @> '[123]'
相关问题