Sql 在JSONB列的哈希数组中查找与列表不匹配的所有值

Sql 在JSONB列的哈希数组中查找与列表不匹配的所有值,sql,json,postgresql,jsonb,Sql,Json,Postgresql,Jsonb,假设我有一个带有JSONB列的表,名为fields。我的表格tbl_1包含以下值 ID Fields ------------------------------------------------------------- 1 [{"label": "Request For"}, {"label": "Requestor"}] 2 [{"label": "Request For"}, {"label": "Meeting"}, {"label": "XYZ"}] 3 [{

假设我有一个带有JSONB列的表,名为
fields
。我的表格
tbl_1
包含以下值

ID   Fields
-------------------------------------------------------------
 1   [{"label": "Request For"}, {"label": "Requestor"}]
 2   [{"label": "Request For"}, {"label": "Meeting"}, {"label": "XYZ"}]
 3   [{"label": "Request For"}, {"label": "Meeting With"}, {"label": "ABC"}]

现在我有一个列表
[“ABC”,“请求”,“ZZZ”,“ABC”]
。我想在单个查询中找到上面列表中的哪个元素不在表中。上述列表的预期输出应为
[“ZZZ”]

使用
where
子句中的
不存在,例如:

with my_table(if, fields) as (
values
    (1, '[{"label": "Request For"}, {"label": "Requestor"}]'::jsonb),
    (2, '[{"label": "Request For"}, {"label": "Meeting"}, {"label": "XYZ"}]'),
    (3, '[{"label": "Request For"}, {"label": "Meeting With"}, {"label": "ABC"}]')
)

select item
from jsonb_array_elements('["ABC", "Request For", "ZZZ", "ABC"]') as item
where not exists (
    select 1
    from my_table
    cross join lateral jsonb_array_elements(fields)
    where value->'label' = item
    )

 item  
-------
 "ZZZ"
(1 row) 

使用
@>
运算符的替代解决方案,可提供更简单的执行计划:

select item
from jsonb_array_elements('["ABC", "Request For", "ZZZ", "ABC"]') as item
where not exists (
    select 1
    from my_table
    where fields @> jsonb_build_array(jsonb_build_object('label', item))
    )
您可以在实际数据上测试哪一个更快。

这同样有效

SELECT 
    a.col
FROM
    tbl_1  t
    CROSS JOIN LATERAL
    jsonb_to_recordset(t.fields) as j("label" text)
    right join 
    (
        select unnest(ARRAY['ABC', 'Request For', 'ZZZ', 'ABC'])as col
    ) a
    on j."label" = a.col
where j."label" is null

为什么“ABC”在输出中?它出现在第三层row@AnuraagVeerapaneni是的,它在那里是因为它出现在第三行。您想找到上面列表中的哪个元素不在表中。但是ABC出现在表格中,为什么它应该出现在输出中?@AnuraagVeerapaneni感谢您指出这一点