MySQL分组查询时按条件过滤关联记录的问题
问题分析与解决方案
你的需求是基于关联的两张表(table1和table2通过question_id关联,table2中同一question_id对应多条用户记录),找出那些**未关联user_id='10'**的question_id,或存在非10用户的question_id。原SQL的问题在于:
- SELECT直接取table2.user_id不符合分组逻辑,分组后需用聚合函数处理字段
- GROUP BY中的CASE语句逻辑混乱,无法实现筛选目标
- WHERE子句会提前过滤行,破坏LEFT JOIN的效果(比如会过滤掉table2无匹配的NULL记录)
正确写法1:找出完全未关联user_id='10'的question_id
包括table2中没有该question_id任何记录的情况:
SELECT table1.question_id FROM table1 LEFT JOIN table2 ON table1.question_id = table2.question_id AND table2.user_id = '10' -- 只关联user_id=10的记录 GROUP BY table1.question_id HAVING COUNT(table2.user_id) = 0; -- 计数为0说明无匹配的10用户
正确写法2:找出存在非10用户的question_id
如果需要找出那些有其他用户(不管是否关联过10)的question_id:
SELECT table1.question_id FROM table1 LEFT JOIN table2 ON table1.question_id = table2.question_id GROUP BY table1.question_id -- 判断是否存在非10的用户,或无任何table2记录 HAVING SUM(CASE WHEN table2.user_id != '10' THEN 1 ELSE 0 END) > 0 OR COUNT(table2.user_id) = 0;
如果不需要包含无table2记录的question_id,去掉最后的OR COUNT(table2.user_id) = 0即可。
关于WHERE子句的误区
不要在WHERE里加table2.user_id != '10',因为:
- LEFT JOIN生成的table2字段为NULL的记录,会被这个条件过滤(NULL与任何值比较都为UNKNOWN,WHERE会排除这类行)
- 若某个question_id同时关联了10和其他用户,WHERE会过滤掉10的记录,但分组后仍会保留该question_id,但逻辑上你需要的是分组后的整体判断,而非提前过滤行,因此应该用HAVING子句在分组后做筛选。
内容的提问来源于stack exchange,提问作者Mohammad Golmohammadi
相关产品推荐
相关产品推荐

