我有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]}
我正在努力选择所有包含123
或456
的记录。这可能吗?
将123
或456
包含为子查询,如:
select * from tableA where (data->'sequence') in (select data_id from tableB);
答案 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]'