多对多关联下如何查询同时包含指定分类的产品?
解决方案:查询同时属于多个分类的产品
当前使用IN条件的查询会返回至少包含其中一个分类的产品,而非同时包含所有指定分类的产品。要实现“同时拥有多个分类”的查询,需通过分组并统计关联分类的数量来过滤结果。
正确的SQL实现
SELECT p0_.id AS id_0, p0_.titre AS titre_1 FROM produit p0_ INNER JOIN produit_categorie_produit p2_ ON p0_.id = p2_.produit_id INNER JOIN categorie_produit c1_ ON c1_.id = p2_.categorie_produit_id WHERE c1_.id IN (11, 197) GROUP BY p0_.id, p0_.titre HAVING COUNT(DISTINCT c1_.id) = 2 ORDER BY titre_1 ASC LIMIT 12;
关键逻辑说明:
- 使用
INNER JOIN替代LEFT JOIN,确保只返回存在目标分类关联的产品 WHERE子句筛选出目标分类IDGROUP BY按产品分组,统计每个产品关联的目标分类数量HAVING子句确保产品关联的目标分类数量等于指定的分类总数(此处为2),以此保证产品同时拥有所有指定分类
Symfony Doctrine 实现
$categoryIds = [11, 197]; $qb = $this->createQueryBuilder('p') ->innerJoin('p.categories', 'c') ->addSelect('p.titre as titre') ->where('c.id IN (:catIds)') ->setParameter('catIds', $categoryIds) ->groupBy('p.id') ->having('COUNT(DISTINCT c.id) = :categoryCount') ->setParameter('categoryCount', count($categoryIds)) ->orderBy('p.titre', 'ASC') ->setMaxResults(12); return $qb->getQuery();
关键调整:
- 替换
leftJoin为innerJoin,过滤掉无目标分类关联的产品 - 添加
groupBy和having子句,通过统计分类数量确保产品同时包含所有指定分类 - 使用
count($categoryIds)动态设置需要匹配的分类数量,让代码支持任意数量的分类ID查询
内容的提问来源于stack exchange,提问作者Alexandre Lapille
相关产品推荐
相关产品推荐

