[英]query for many to many record matching
I have table tag_store like below我有如下表tag_store
I want to filter the ids which has all tag provided in a like我想过滤所有标签中提供的 id
SELECT st.id from public."tag_store" st
inner join
(SELECT x.tg_type,x.tg_value FROM json_to_recordset
('[{ "tg_type":1, "tg_value ":"cd"},{ "tg_type":2,"tg_value ":"tg"},{ "tg_type":3,"tg_value ":"po" }] '::json)
AS x (tg_type int, tg_value TEXT)) ftg
on st.tg_type= ftg.tg_type
and st.tg_value = ftg.tg_value order by st.id;
My desired output is it should have output onlye id 1 as it has all three tg_value and tg_id matched..我想要的 output 是否应该只有 output id 1 因为它所有三个 tg_value 和 tg_id 都匹配..
Please help, what should I change, or is there any better alternate请帮忙,我应该改变什么,或者有没有更好的替代品
Thanks谢谢
I would aggregate the values into a JSON array and use the @>
operator to filter those that have all of them:我会将这些值聚合到 JSON 数组中,并使用
@>
运算符过滤所有这些值:
with tags as (
select id, jsonb_agg(jsonb_build_object('tg_id', tag_id, 'tg_value', tag_value)) all_tags
from tag_store
group by id
)
select *
from tags
where all_tags @> '[{"tg_id":1, "tg_value": "cd"},
{"tg_id":2, "tg_value": "tg"},
{"tg_id":3, "tg_value": "po"}]'
;
You can also do that directly in a HAVING clause if you want如果需要,您也可以直接在 HAVING 子句中执行此操作
select id
from tag_store
group by id
having jsonb_agg(jsonb_build_object('tg_id', tag_id, 'tg_value', tag_value))
@> '[{"tg_id":1, "tg_value": "cd"},
{"tg_id":2, "tg_value": "tg"},
{"tg_id":3, "tg_value": "po"}]'
;
Note that this will return IDs that have additional tags apart from those in the comparison array.请注意,这将返回除了比较数组中的标签之外还有其他标签的 ID。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.