【场景】:列合并、select条件语句、join on 条件

【分类】:连接查询、嵌套子查询

分析思路

难点:

1.统计出“当月均完成试卷数”不小于3的用户们,with子查询和from子查询一定要去重,in子查询不用去重

2.多表做连接

3.join on 的连接条件中相当于where条件,是可以写每个表单独的条件

(1)找到高难度SQL试卷得分平均值大于80并且是7级的红名大佬

​ [条件]:where tag = 'SQL' and difficulty = 'hard' and level = '7' group by uid having avg(score) >= 80

(2)统计用户2021年试卷总完成次数

​ [条件]:year(submit_time) = 2021

(3)统计用户2021年题目总练习次数

​ [条件]:year(submit_time) = 2021

(4)分别将符合条件的用户的试卷总完成数和题目总完成数两列合并,按试卷完成数升序,按题目练习数降序

​ [使用]:多表左连接使用 left join using( ); order by exam_cnt asc,question_cnt desc

最终结果

select 查询结果 [用户ID; 试卷总完成数; 题目总完成数]
from 从哪张表中查询数据[多个join连接的表]
where 查询条件 [高难度SQL试卷得分平均值大于80并且是7级的红名大佬]
order by 对查询结果排序 [按试卷完成数升序,按题目练习数降序];

扩展:

前往查看MySQL 合并查询join 查询出的不同列合并到一个表中

求解代码

方法一:

with 子查询

with
    temp as(
        #找到高难度SQL试卷得分平均值大于80并且是7级的红名大佬
    	select 
            uid
        from exam_record
        join examination_info using(exam_id)
        join user_info using(uid)
        where tag = 'SQL'
        and difficulty = 'hard'
        and level = '7'
        group by uid having avg(score) >= 80
    ),
    main as(
        #统计2021年试卷总完成次数
    	select 
            uid,
            count(submit_time) as exam_cnt
        from exam_record
        where year(submit_time) = 2021
        group by uid
    ),
    attr as(
        #统计2021年题目总练习次数
    	select 
            uid,
            count(submit_time) as question_cnt
        from practice_record
        where year(submit_time) = 2021
        group by uid
    )
#分别将符合条件的用户的试卷总完成数和题目总完成数两列合并,按试卷完成数升序,按题目练习数降序
select 
    uid,
    exam_cnt,
    if(question_cnt is null,0,question_cnt)
from temp
left join main using(uid)
left join attr using(uid)
order by exam_cnt asc,question_cnt desc

方法二

from 子查询、in 子查询

# 分别找第二列和第三列
select 
    uid,
    exam_cnt,
    if(question_cnt is null,0,question_cnt)
from(
    #统计2021年试卷总完成次数
    select
        uid,
        count(submit_time) as exam_cnt
    from exam_record
    where year(submit_time) = 2021
    group by uid
     ) main
left join(
    #统计2021年题目总练习次数
    select 
        uid,
        count(submit_time) as question_cnt
    from practice_record
    where year(submit_time) = 2021
    group by uid
    ) attr using(uid)
where uid in(
    #找到高难度SQL试卷得分平均值大于80并且是7级的红名大佬
    select 
        uid
    from exam_record
    join examination_info using(exam_id)
    join user_info using(uid)
    where tag = 'SQL'
    and difficulty = 'hard'
    and level = '7'
    group by uid having avg(score) >= 80
    )
order by exam_cnt asc,question_cnt desc

方法三

with 子查询、in 子查询

with
	main as(
        #统计2021年试卷总完成次数
    	select 
            uid,
            count(submit_time) as exam_cnt
        from exam_record
        where year(submit_time) = 2021
        group by uid
    ),
    attr as(
        #统计2021年题目总练习次数
    	select 
            uid,
            count(submit_time) as question_cnt
        from practice_record
        where year(submit_time) = 2021
        group by uid
    )

#分别将符合条件的用户的试卷总完成数和题目总完成数两列合并,按试卷完成数升序,按题目练习数降序
select
    uid,
    exam_cnt,
    if(question_cnt is null,0,question_cnt)
from main
left join attr using(uid)
where uid in(
    select
        uid
    from exam_record
    join examination_info using(exam_id)
    join user_info using(uid)
    where tag = 'SQL'
    and difficulty = 'hard'
    and level = '7'
    group by uid having avg(score) >= 80
)
order by exam_cnt asc,question_cnt desc

方法四

多表连接

select 
    uid,
    exam_cnt,
    if(question_cnt is null,0,question_cnt)
from exam_record
join examination_info using(exam_id)
join user_info using(uid)
left join(
    #统计2021年试卷总完成次数
    select
        uid,
        count(submit_time) as exam_cnt
    from exam_record
    where year(submit_time) = 2021
    group by uid
     ) main using(uid)
left join(
    #统计2021年题目总练习次数
    select 
        uid,
        count(submit_time) as question_cnt
    from practice_record
    where year(submit_time) = 2021
    group by uid
    ) attr using(uid)
#找到高难度SQL试卷得分平均值大于80并且是7级的红名大佬
where tag = 'SQL'
and difficulty = 'hard'
and level = '7'
group by uid having avg(score) >= 80
order by exam_cnt asc,question_cnt desc

方法五

不使用列合并 使用 join on 条件

select
    a.uid,
    count(distinct a.exam_id) as exam_cnt,#统计2021年试卷总完成次数
    count(distinct b.id) as question_cnt#统计2021年题目总练习次数
from exam_record a
left join practice_record b
on a.uid = b.uid and year(a.submit_time) = 2021 and year(b.submit_time) = 2021
where a.uid in(
    #找到高难度SQL试卷得分平均值大于80并且是7级的红名大佬
    select 
        a.uid
    from exam_record a
    join examination_info using(exam_id)
    join user_info using(uid)
    where tag = 'SQL'
    and difficulty = 'hard'
    and level = '7'
    group by a.uid having avg(score) >= 80) 
group by a.uid
order by exam_cnt,question_cnt desc