先看到题:统计复旦用户8月练题情况 牛客中的 原地址
通过这个题我们来探讨where和on
描述
题目: 现在运营想要了解复旦大学的每个用户在8月份练习的总题目数和回答正确的题目数情况,请取出相应明细数据,对于在8月份没有练习过的用户,答题数结果返回0.
题意:让找出8月份复旦大学的做题情况
select U.device_id as device_id,university,
count(question_id) as question_cnt,
sum(if(result = 'right',1,0)) as right_question_cnt
from user_profile as U left join question_practice_detail as Q
on U.device_id = Q.device_id and month(date) = '8'
where university = '复旦大学'
group by U.device_id
为啥要把 连接表判断月份 和 判断大学分开写呢? 其实也是可以和这写的
先说它们的区别
这里边就涉及了on和where 的区别
on 是不具备过滤功能的,它只是把两个表连接在一起了,没有过滤去我们想要的数据。
但是我们要找出 我们筛序的是 复旦大学的学生。
那么此时就用到where了,where是具备过滤功能的,它能拿出我们想要的数据。
按照上边的说法 你是不是有个小疑问呀! 那为什么把8月份写在后边呀!它不是不具备过滤功能吗?
其实不然:
首先明白 on 和 where 在我们写的sql中 执行的时间
on是在 生成这个临时表的时候作用的,而where是在表生成之后作用的。另外我们使用的是left join(左外连接)查询的 ,on 后边的条件只对右边的表有过滤作用 也就是 question_practice_detail 表,对于 user_profile 没有 ,但是此时我们有想要过滤新表的数据,那么就需要 使用where来进行过滤
同理(right join) 右外连接
对于(inner join)内连接 其实他是先生成表在执行where 或 on 后边的语句的 ,那么用where或on 都一样了
把月份和大学放在一起
select U.device_id as device_id,university,
count(question_id) as question_cnt,
sum(if(result = 'right',1,0)) as right_question_cnt
from user_profile as U left join question_practice_detail as Q
on U.device_id = Q.device_id
where university = '复旦大学' and (month(date) = '8' or month(date) is null)
group by U.device_id