[英]querying json keys which intersect in postgres jsonb
How do i query for jsonb keys which intersect: 我如何查询相交的jsonb键:
Ex: 例如:
kv | column1
-----------------------------------------------------------
[{"k1": "v1"}, {"k2": "v22"}] | web
[{"k10": "v5"}, {"k9": "v21"}] | mobile
[{"k1": "v1"}, {"k5": "v24"}] | web1
[{"k5": "v1"}, {"k55": "v24"}] | web1
here, row 1 and row 3 has key k1
and row 3 and row 4 has key k5
. 在这里,第1行和第3行具有键
k1
,第3行和第4行具有键k5
。
So, the answer should be rows 1,3 & 4. 因此,答案应该是第1、3和4行。
You can try this : 您可以尝试以下方法:
--This part is to simulate your table
with yourTable as (
select (string_to_array(t,'|'))[1]::jsonb kv,(string_to_array(t,'|'))[2] column1 from (
select unnest(string_to_array($$[{"k1": "v1"}, {"k2": "v22"}] | web
[{"k10": "v5"}, {"k9": "v21"}] | mobile
[{"k1": "v1"}, {"k5": "v24"}] | web1
[{"k5": "v1"}, {"k55": "v24"}] | web1$$::character varying,E'\n')) t
) b
)
-- This is your request :
select distinct kv,column1 from (
select *,count(*) over (partition by elt) nb_inter from (
select kv,column1,jsonb_object_keys(jsonb_array_elements(kv)) elt from yourTable
) a
) b
where nb_inter >1
Assuming the following setup: 假设以下设置:
create table data (id serial, kv jsonb, col1 text);
insert into data (kv, col1)
values
('[{"k1": "v1"}, {"k2": "v22"}]', 'web'),
('[{"k10": "v5"}, {"k9": "v21"}]', 'mobile'),
('[{"k1": "v1"}, {"k5": "v24"}]', 'web1'),
('[{"k5": "v1"}, {"k55": "v24"}]', 'web1');
You can get those rows by first normalizing the data, then doing a self join on the normalized data. 您可以通过首先规范化数据,然后对规范化的数据进行自联接来获取这些行。 To normalize the data you need to unnest the JSON values twice: once for flattening the arrays and then another time to extract the keys from the JSON values:
要规范化数据,您需要取消JSON值的嵌套两次:一次用于展平数组,另一次从JSON值提取键:
with normalized as (
select d.id, t2.*
from data d
join jsonb_array_elements(kv) as t1(kv) on true
join jsonb_each_text(t1.kv) as t2(k,val) on true
)
select n1.*
from normalized n1
where exists (select *
from normalized n2
where n1.id <> n2.id
and n1.k = n2.k);
The above returns: 以上返回:
id | k | val
---+----+----
1 | k1 | v1
3 | k1 | v1
3 | k5 | v24
4 | k5 | v1
Or use it with an IN condition to get the original rows: 或将其与IN条件一起使用以获取原始行:
with normalized as (
select d.id, t2.*
from data d
join jsonb_array_elements(kv) as t1(kv) on true
join jsonb_each_text(t1.kv) as t2(k,val) on true
)
select *
from data
where id in (select n1.id
from normalized n1
where exists (select *
from normalized n2
where n1.id <> n2.id
and n1.k = n2.k))
returns: 返回:
id | kv | col1
---+--------------------------------+-----
1 | [{"k1": "v1"}, {"k2": "v22"}] | web
3 | [{"k1": "v1"}, {"k5": "v24"}] | web1
4 | [{"k5": "v1"}, {"k55": "v24"}] | web1
This type of query would be easier if you didn't store the key/value pairs in an array, '{"k1": "v1", "k2": "v22"}'
would make a lot more sense to me than [{"k1": "v1"}, {"k2": "v22"}]
如果您没有将键/值对存储在数组中,则这种类型的查询会更容易,
'{"k1": "v1", "k2": "v22"}'
对我而言比[{"k1": "v1"}, {"k2": "v22"}]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.