我有一个PostgreSQL表(生物),如下所示:
| id <integer> | json <jsonb> |
-------------------------------
| 1 | {"name": "Grooper", "weaknesses":[{"type":"Fire", "value":2},{"type":"Dark", "value":2}]} |
| 2 | {"name": "Zik", "weaknesses":[{"type":"Fire", "value":2}]} |
我正在尝试创建一个过滤弱点类型的查询,以便我可以过滤所有类型为Fire
或 Dark
的弱点的生物(包含任何一个),但也查询类型为Fire
和 Dark
的弱点的生物(必须包含两者)。
我找到了一个适用于Fire
或 Dark
的查询:
select
distinct c.*
from
creatures c,
jsonb_array_elements(json->'weaknesses') as weakness
where weakness->'type' ?| array['Fire','Dark']
如何让此查询用于过滤Fire
和 Dark
类型的生物?
更新:
我有一个似乎可以实现我想要的查询,但看起来并不漂亮。有什么提示吗?
SELECT * FROM creatures
WHERE 'Fire' in (SELECT jsonb_array_elements(json->'weaknesses')->>'type')
AND 'Dark' in (SELECT jsonb_array_elements(json->'weaknesses')->>'type')
答案 0 :(得分:1)
此处的问题是您必须“查看”数组中的jsonb
值,以便您无法使用?&
运算符。相反,使用?
运算符找到相应的键,并仅选择具有两个匹配的行:
SELECT DISTINCT id, json
FROM creatures
JOIN LATERAL jsonb_array_elements(json->'weaknesses') ON value ? 'Dark' OR value ? 'Fire'
GROUP BY 1, 2
HAVING count(id) = 2;
顺便说一句,如果id
是唯一的(主键可能是?)那么SELECT DISTINCT ON (id) id, json ...
要快得多,因为不需要检查jsonb
文档来删除重复项。