如何无需重复子查询,排除结果集中存在子分类的父分类?
解决方案
可以只用当前结果集实现需求,核心是先把初始查询的结果一次性缓存下来,避免重复执行全文检索。这里用CTE(公共表表达式)就能轻松做到:
方法一:基于CTE的NOT IN查询
WITH filtered_cats AS ( SELECT id, cat_name, cat_parent FROM transport WHERE MATCH (cat_name) AGAINST ('car*' IN BOOLEAN MODE) ) SELECT fc.id, fc.cat_name, fc.cat_parent FROM filtered_cats fc WHERE fc.id NOT IN ( SELECT cat_parent FROM filtered_cats WHERE cat_parent != 0 -- 排除顶级分类的父ID(0) );
方法二:左关联筛选(性能更优)
如果数据集较大,左关联的方式通常比NOT IN效率更高:
WITH filtered_cats AS ( SELECT id, cat_name, cat_parent FROM transport WHERE MATCH (cat_name) AGAINST ('car*' IN BOOLEAN MODE) ) SELECT fc.id, fc.cat_name, fc.cat_parent FROM filtered_cats fc LEFT JOIN filtered_cats child ON fc.id = child.cat_parent WHERE child.id IS NULL;
说明
- CTE的
filtered_cats只执行一次全文检索,把所有符合car*匹配条件的分类都暂存起来,后续的筛选逻辑都基于这个临时数据集,完全避免了重复写MATCH条件的冗余。 - 你之前尝试的
id != cat_parent逻辑不对,它只是排除"自身为父类"的异常数据,和"是否存在子分类"无关;而id NOT IN (cat_parent)是语法逻辑错误,因为cat_parent是单一行的字段值,不是一个集合,所以无法起到筛选作用。
内容的提问来源于stack exchange,提问作者Paul
相关产品推荐
相关产品推荐

