我想使用SQL检查JSONB列中属性的存在。
使用这是我可以检查属性是否等于值:
SELECT count(*) AS "count" FROM "table" WHERE column->'node' @> '[{"Attribute":"value"}]'
我使用什么语法检查Attribute是否存在?
答案 0 :(得分:0)
通常,您将检查是否为空:
SELECT count(*) AS "count" FROM "table"
WHERE column->'node'->'Attribute' is not null
答案 1 :(得分:0)
?
运算符的意思是Does the string exist as a top-level key within the JSON value?,但是,您要检查嵌套嵌套json对象数组中是否存在键,因此无法直接使用该运算符。您必须取消嵌套数组。
样本数据:
create table my_table(id serial primary key, json_column jsonb);
insert into my_table (json_column) values
('{"node": [{"Attribute":"value"}, {"other key": 0}]}'),
('{"node": [{"Attribute":"value", "other key": 0}]}'),
('{"node": [{"Not Attribute":"value"}]}');
在横向联接中使用jsonb_array_elements()
来查找键是否存在于数组的任何元素中:
select
id,
value,
value ? 'Attribute' as key_exists_in_object
from my_table
cross join jsonb_array_elements(json_column->'node')
id | value | key_exists_in_object
----+----------------------------------------+----------------------
1 | {"Attribute": "value"} | t
1 | {"other key": 0} | f
2 | {"Attribute": "value", "other key": 0} | t
3 | {"Not Attribute": "value"} | f
(4 rows)
但这并不是您所期望的。您需要汇总数组的结果:
select
id,
json_column->'node' as array,
bool_or(value ? 'Attribute') as key_exists_in_array
from my_table
cross join jsonb_array_elements(json_column->'node')
group by id
order by id
id | array | key_exists_in_array
----+--------------------------------------------+---------------------
1 | [{"Attribute": "value"}, {"other key": 0}] | t
2 | [{"Attribute": "value", "other key": 0}] | t
3 | [{"Not Attribute": "value"}] | f
(3 rows)
嗯,这看起来有点复杂。您可以使用以下功能使其更容易:
create or replace function key_exists_in_array(key text, arr jsonb)
returns boolean language sql immutable as $$
select bool_or(value ? key)
from jsonb_array_elements(arr)
$$;
select
id,
json_column->'node' as array,
key_exists_in_array('Attribute', json_column->'node')
from my_table
id | array | key_exists_in_array
----+--------------------------------------------+---------------------
1 | [{"Attribute": "value"}, {"other key": 0}] | t
2 | [{"Attribute": "value", "other key": 0}] | t
3 | [{"Not Attribute": "value"}] | f
(3 rows)