我有一个 PostgreSQL 表(creatures),如下所示:
| 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')
最佳答案
这里的问题是您必须“查看”数组中的 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
文件不必检查以删除重复项。
关于带有哈希元素数组的 PostgreSQL jsonb_array_elements,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36732784/