其实这道题目考察的知识点最主要的是,My SQL语句的执行顺序问题,不同的执行顺序会有不同的运行结果。(以下的解释都基于本题)

一开始大家一定是先把两张表连接起来,再用where去筛选。但是本题目是要求找出复旦大学中所有用户8月份的答题情况,复旦大学的用户中,有可能存在8月份没有答题的用户。若先把两张表连起来再用where筛选限定条件,那么运行结果会把属于复旦大学但是没有答题的用户剔除了,不符合本题要求。

我们要的结果是:复旦大学所有用户8月的作答情况,包含没有作答过的。

思路&方法:先把所有8月份的用户(包括null值)选出来,再从这部分用户当中只选复旦的。

注意的点:

  1. 限定条件嵌套在left join里面和限定条件在where之后两者的区别。
  2. 先分组后筛选和先筛选后分组的区别;
#写法一:
SELECT a.device_id,
       university,
       count(question_id) as question_cnt,
       sum(if(b.result = 'right',1,0)) as right_question_cnt
FROM user_profile a 
LEFT JOIN question_practice_detail b ON a.device_id = b.device_id AND MONTH(`date`)=8
WHERE university = "复旦大学"
GROUP BY b.device_id;

这种写法是先筛选后分组。 alt

#写法二:
SELECT a.device_id,
       university,
       count(question_id) as question_cnt,
       sum(if(b.result = 'right',1,0)) as right_question_cnt
FROM user_profile a 
LEFT JOIN question_practice_detail b ON a.device_id = b.device_id  AND MONTH(`date`)=8

GROUP BY a.device_id

HAVING university = "复旦大学";

这种写法是先分组再筛选,但是这里千万要注意,group by分组后一定要跟having而不能用where,其次就是group by是有去重和剔除null的作用,所有这里的分组依据一定要用第一张表。 alt alt