知识

外连接

只限制一张表中的数据必须满足连接条件,而另一张表中数据可以不满足连接条 件。

外连接的语法格式为:

SELECT … FROM 表1 LEFT | RIGHT [OUTER] 
JOIN 表2 ON <连接条件>
  • left join: 包含左表的所有行,对应的右表行可能为空
  • right join: 包含右表的所有行,对应的左表行可能为空
  • full join: 只包含左右表都匹配并且不为空的行

例52.查询学生的选课情况,包括选修了课程的学生和没有选修课程的学生。

SELECT 学生表.学号, 姓名, 课程号, 成绩
FROM 学生表 LEFT JOIN 成绩表
ON 学生表.学号 = 成绩表.学号

例53.查询所有学生的学号、姓名、班号和班名,即使该学生无班号也列出学生。

SELECT 学号, 姓名,学生表.班号, 班名
FROM 学生表 LEFT JOIN 班级表
ON 学生表.班号 = 班级表.班号

例54.查询21226P班没有选课的学生,列出学生姓名和性别。

SELECT 姓名,性别
FROM 学生表 S LEFT JOIN 成绩表 g 
ON S.学号 = g.学号
WHERE 班号 = '21226P'
AND g.学号 IS NULL

例55. 统计21226P班每个学生的选课门数,包括没有选课的学生。

SELECT S.学号 AS 学号,
COUNT(课程号) AS 选课门数
FROM 学生表 S LEFT JOIN 成绩表 g 
ON S.学号 = g.学号
WHERE 班号 = '21226P’
GROUP BY S.学号

解题

题目中的“用户在某天刷题后第二天还会再来刷题”需要通过比较同一个device_id在date和date+1两天都有答题数据。

需要通过datediff(date1,date2)=1来判断是否连续两天都有答题数据。

因为需要计算用户的平均次日留存率,如果用户次日没有留存,则因为不符合连接条件而为空,所以需要通过外连接来实现。除数就是有数据的COUNT DISTINCT值,被除数就是全数据的COUNT DISTINCT值。

题解

题目:现在运营想要查看用户在某天刷题后第二天还会再来刷题的平均概率。请你取出相应数据。

SELECT count(distinct q2.device_id,q2.date)/count(distinct q1.device_id,q1.date) as avg_ret
FROM question_practice_detail as q1 left outer join question_practice_detail as q2 
on q1.device_id=q2.device_id and datediff(q2.date,q1.date)=1; 

示例:question_practice_detail

根据示例,你的查询应返回以下结果: