同表中查找匹配指定多CategoryID的相似记录(IN子句失效)
解决同时匹配多个CategoryID的SQL查询问题
你的问题在于原来的IN子句会返回所有包含任一目标CategoryID的记录,但你需要的是同时包含所有目标CategoryID(允许额外存在其他CategoryID)的BlogID,所以得换个思路来实现。
下面给你几种可行的解决方案:
方法1:GROUP BY + HAVING 统计匹配数量
这种方法适合动态获取目标CategoryID的场景(比如你通过BlogID=1拿到对应的CategoryID集合),不需要硬编码具体的ID值:
SELECT BlogID FROM tblBlogCategory WHERE CategoryID IN (SELECT CategoryID FROM tblBlogCategory WHERE BlogID = 1) GROUP BY BlogID -- 统计当前BlogID匹配到的目标CategoryID数量,等于目标集合的总数 HAVING COUNT(DISTINCT CategoryID) = (SELECT COUNT(DISTINCT CategoryID) FROM tblBlogCategory WHERE BlogID = 1)
原理说明:
- 先通过子查询拿到BlogID=1对应的所有CategoryID(这里是1和2)
- 过滤出表中所有属于这些CategoryID的记录
- 按BlogID分组,统计每个分组里不同的CategoryID数量
- 只有当数量等于目标集合的总数(2)时,说明这个BlogID包含了所有目标CategoryID,不管有没有额外的(比如CategoryID=3)
方法2:多EXISTS子查询(直观易懂)
如果目标CategoryID是固定的(比如你明确知道是1和2),可以用多个EXISTS来逐一验证BlogID是否包含每个CategoryID:
SELECT DISTINCT bc.BlogID FROM tblBlogCategory bc -- 检查当前BlogID是否包含CategoryID=1 WHERE EXISTS ( SELECT 1 FROM tblBlogCategory bc1 WHERE bc1.BlogID = bc.BlogID AND bc1.CategoryID = 1 ) -- 同时检查是否包含CategoryID=2 AND EXISTS ( SELECT 1 FROM tblBlogCategory bc2 WHERE bc2.BlogID = bc.BlogID AND bc2.CategoryID = 2 )
这种方法逻辑直白,每个EXISTS都确保BlogID存在对应的CategoryID记录,最终返回的就是同时满足所有条件的BlogID。
方法3:多表JOIN
和EXISTS思路类似,通过多次JOIN来强制BlogID同时存在多个CategoryID的记录:
SELECT DISTINCT bc.BlogID FROM tblBlogCategory bc -- 关联到CategoryID=1的记录 JOIN tblBlogCategory bc1 ON bc.BlogID = bc1.BlogID AND bc1.CategoryID = 1 -- 关联到CategoryID=2的记录 JOIN tblBlogCategory bc2 ON bc.BlogID = bc2.BlogID AND bc2.CategoryID = 2
JOIN操作会自动过滤掉那些没有同时匹配两个CategoryID的BlogID,最后去重得到结果。
以上三种方法都能满足你的需求,比如示例中的BlogID=3会被正确返回,因为它同时包含CategoryID=1、2,即使还有3也不影响结果。
内容的提问来源于stack exchange,提问作者Jeeten Parmar
相关产品推荐
相关产品推荐

