如何筛选含css标签的问题且保留jsonb_agg中的全部标签?
解决方法
你的问题出在WHERE tags.name = 'css'子句的执行时机——它在聚合前就过滤掉了所有非"css"标签的关联行,所以最终聚合结果只能保留css标签。要在筛选出带css标签的问题的同时保留所有标签,可以用以下两种方法:
方法1:先筛选目标问题ID,再关联所有标签
通过子查询先找出所有带有css标签的问题ID,再基于这些ID拉取对应的所有标签并聚合:
SELECT q.id, jsonb_agg(to_jsonb(t)) AS tags FROM questions q JOIN questions_tags qt ON q.id = qt.question_id JOIN tags t ON qt.tag_id = t.id WHERE q.id IN ( SELECT qt_inner.question_id FROM questions_tags qt_inner JOIN tags t_inner ON qt_inner.tag_id = t_inner.id WHERE t_inner.name = 'css' ) GROUP BY q.id ORDER BY q.id LIMIT 20;
方法2:用HAVING子句筛选目标问题
先聚合所有问题的标签,再通过HAVING子句筛选出至少包含一个css标签的问题:
SELECT q.id, jsonb_agg(to_jsonb(t)) AS tags FROM questions q LEFT JOIN questions_tags qt ON q.id = qt.question_id LEFT JOIN tags t ON qt.tag_id = t.id GROUP BY q.id HAVING bool_or(t.name = 'css') ORDER BY q.id LIMIT 20;
注意:如果问题可能没有标签(虽然你的需求是找带css标签的,所以这种情况不会出现),可以保留LEFT JOIN;如果确定目标问题都有至少一个标签,用JOIN性能会更好。
内容的提问来源于stack exchange,提问作者Dmitriy Zhuravlev
相关产品推荐
相关产品推荐

