HQL,SQL刷题,尚硅谷

目录

相关表数据:

​编辑

题目及思路解析:

复杂查询,子查询

1、查询所有课程成绩均小于60分的学生的学号、姓名

2、查询没有学全所有课的学生的学号、姓名

3、查询出只选修了三门课程的全部学生的学号和姓名

总结归纳:

知识补充:


相关表数据:

1、student_info

2、score_info

3、course_info

题目及思路解析:

复杂查询,子查询

1、查询所有课程成绩均小于60分的学生的学号、姓名

tips:这里关键在所有课程,可以用sum(if())函数方法

代码1:

复制代码
select
    t1.stu_id,
    stu_name
from
    (
     select
        stu_id,
        sum(if(score<60,0,1)) flag
    from score_info
    group by stu_id
    having flag=0
    )t1
join student_info
on t1.stu_id=student_info.stu_id;

思路1:

这个解法比较常规。首先第一层(里面的子查询)按照学号分组,得到每个学生所有课程考试成绩,然后用sum(if())方法判断求和,相当于判断每个课程的成绩,小于60返回0,反之返回1,最终统计所有课程sum=0的即所有课程均小于60,最后嵌套第二层连接student_info得到学生姓名,输出结果

代码2:

复制代码
select
     t1.stu_id,
     stu_name
 from(
      select
        stu_id,
        max(score) max_score
    from score_info
    group by stu_id
    having max_score<60
     )t1
 join student_info
 on t1.stu_id=student_info.stu_id;

思路2:

这个解法就比较妙了。关键在第一层(子查询),同样式分组得到每个学生所有课程考试成绩,但是它先求出每个学生的所有成绩中最高分的,然后筛选最高分中小于60(最高分都小于60了,其它也一定小于60),这样就可以得到全部课程成绩均小于60

结果:

2、查询没有学全所有课的学生的学号、姓名

代码1:

复制代码
select
    distinct t1.stu_id,
    stu_name
from (
    select
        stu_id
    from score_info
    group by stu_id,course_id
    having count(course_id)<
            (
           select count(course_id)
           from course_info )
     )t1
join student_info
on t1.stu_id=student_info.stu_id;

代码2:

复制代码
select
    s.stu_id,
    s.stu_name
from student_info s
left join score_info sc on s.stu_id = sc.stu_id
group by s.stu_id, s.stu_name
having count(course_id) < (select count(course_id) from course_info);

思路:

代码1两层嵌套,逻辑比较清晰吧,首先第一层获取从course_info表总课程数,接着第二层查询score_info表 按照学号和课程ID分组,得到每个学生所有课程考试成绩,筛选课程数小于总课程数的学生,然后第三层Join student_info表得到学生姓名,最后输出结果(需要去重)

代码2一层嵌套,不同点在于它查询的是studen_info表,然后join score_info表,筛选部分一样
总的来说,代码2比较简洁一点

结果:

3、查询出只选修了三门课程的全部学生的学号和姓名

代码1:

复制代码
select
    t1.stu_id,
    stu_name
from (
    select
        stu_id
    from score_info
    group by stu_id
    having count(course_id)=3
     )t1
join student_info
on t1.stu_id=student_info.stu_id;

代码2:

复制代码
select
    s.stu_id,
    s.stu_name
from student_info s
join (
    select
        stu_id,
        count(course_id) course_count
    from score_info
    group by stu_id
    having course_count =3
    ) t1
on s.stu_id = t1.stu_id;

思路:

这题比较简单。

代码1 ,首先第一层按照stu_id分组,得到每个学生所有课程考试成绩,然后统计course_id数=3的学生,然后第二层连接student_info表,输出结果

代码2主要不同在于它把第一层查询表结果直接与student_info表join连接

结果:

总结归纳:

这几道题主要是考察复杂查询的子查询, Join连接等

知识补充:

关于sum(if())

  • sum(if():有条件累加,常用于分类筛选统计

  • sum(if)只试用于单个条件判断,如果筛选条件很多,我们可以用sum(case when then else end)来进行多条件筛选

    注意,hive中并没有sum(distinct col1)这种使用方式,我们可以使用sum(col) group by col来达到相同效果.

相关推荐
IndulgeCui5 小时前
【金仓数据库产品体验官】KingbaseES-ORACLE兼容版快速体验
数据库
xhbh6666 小时前
【超全汇总】MySQL服务启动命令手册(Linux+Windows+macOS)(上)
数据库·mysql·程序员·mysql启动命令·数据库启动命令
2301_803554527 小时前
mysql(自写)
数据库·mysql
麦麦大数据8 小时前
vue+Django 双推荐算法旅游大数据可视化系统Echarts mysql数据库 带爬虫
数据库·vue.js·django·可视化·推荐算法·百度地图·旅游景点
成都极云科技8 小时前
裸金属服务器与虚拟机、物理机的核心差异是什么?
运维·服务器·数据库
学习中的程序媛~8 小时前
图数据库neo4j的安装
数据库·neo4j
喂完待续9 小时前
【Big Data】AI赋能的ClickHouse 2.0:从JIT编译到LLM查询优化,下一代OLAP引擎进化路径
大数据·数据库·clickhouse·数据分析·olap·big data·序列晋升
柏油9 小时前
MySQL InnoDB 架构
数据库·后端·mysql
携欢10 小时前
PortSwigger靶场之Blind SQL injection with out-of-band data exfiltration
服务器·sql·microsoft
10km11 小时前
jsqlparser(六):TablesNamesFinder 深度解析与 SQL 格式化实现
java·数据库·sql·jsqlparser