前言
对于Java程序员而言,熟练的编写SQL语句的能力是非常重要的。故本文用于记录我在鱼皮大佬的SQL之母网站SQL之母 - SQL自学网站 (qmlist.net)刷SQL题目的学习,你也可以尝试自己做一遍检验一下自己的SQL水平。
另外对SQL基础还不太了解的同学可以先去看看这篇博客【MySQL篇】 MySQL基础学习-CSDN博客噢
- 空值
请编写一条 SQL 查询语句,从名为 student
的数据表中选择出所有学生的姓名(name)、年龄(age)和成绩(score),要求学生年龄不为空值
select name,age,score from student where age!='';
select name, age, score from student where age is not null;
- 模糊查询
请编写一条 SQL 查询语句,从名为 student
的数据表中选择出所有学生的姓名(name)和成绩(score),要求姓名(name)不包含 “李” 这个字
select name,score from student where name not like '%李%';
- 去重
请编写一条 SQL 查询语句,从名为 student
的数据表中选择出所有不重复的班级 ID(class_id)和考试编号(exam_num)的组合
select distinct class_id,exam_num from student;
- 排序
请编写一条 SQL 查询语句,从名为 student
的数据表中选择出学生姓名(name)、年龄(age)和成绩(score),首先按照成绩从大到小排序,如果成绩相同,则按照年龄从小到大排序
select name,age,score from student order by score desc,age asc;
- 截断
请编写一条 SQL 查询语句,从名为 student
的数据表中选择学生姓名(name)和年龄(age),按照年龄从小到大排序,从第 2 条数据开始、截取 3 个学生的信息
select name,age from student order by age asc limit 1,3;
- 条件分支
假设有一个学生表 student
,包含以下字段:name
(姓名)、age
(年龄)。请你编写一个 SQL 查询,将学生按照年龄划分为三个年龄等级(age_level):60 岁以上为 “老同学”,20 岁以上(不包括 60 岁以上)为 “年轻”,20 岁以下为 “小同学”。
返回结果应包含学生的姓名(name)和年龄等级(age_level),并按姓名升序排序。
select name,case when(age>60) then '老同学' when (age>20) then '年轻' else '小同学' end as age_level from student order by name asc;
扩展:可能很多人和我一样第一次见这样的SQL语句,如果你知道就跳过,这里讲解下:
这样的SQL语句叫条件分支, case when 是 SQL 中用于根据条件进行分支处理的语法。它类似于C语言中的 if else 语句,允许我们根据不同的条件选择不同的结果返回。其SQL语句如下:
select
字段1,
case when (条件1) then 结果1 when (条件2) then 结果2 ELSE 结果3 end as 别名
from
表名;
- 时间
假设有一个学生表 student
,包含以下字段:name
(姓名)、age
(年龄)。
请你编写一个 SQL 查询,展示所有学生的姓名(name)和当前日期(列名为 “当前日期”)
select name, date() as 当前日期 from student
- 字符串操作
假设有一个学生表 student
,包含以下字段:id
(学号)、name
(姓名)。请你编写一个 SQL 查询,筛选出姓名为 ‘热dog’ 的学生,展示其学号(id)、姓名(name)及其大写姓名(upper_name)
select id,name,upper(name) upper_name from student where name='热dog';
- 聚合函数
假设有一个学生表 student
,包含以下字段:id
(学号)、name
(姓名)、class_id
(班级编号)、score
(成绩)。请你编写一个 SQL 查询,汇总学生表中所有学生的总成绩(total_score)、平均成绩(avg_score)、最高成绩(max_score)和最低成绩(min_score)
select sum(score) total_score,avg(score) avg_score,max(score) max_score,min(score) min_score from student;
- 单字段分组
假设有一个学生表 student
,包含以下字段:id
(学号)、name
(姓名)、class_id
(班级编号)、score
(成绩)。请你编写一个 SQL 查询,统计学生表中每个班级的平均成绩(avg_score)
select class_id,avg(score) avg_score from student group by class_id;
- 多字段分组
假设有一个学生表 student
,包含以下字段:id
(学号)、name
(姓名)、class_id
(班级编号)、exam_num
(考试次数)、score
(成绩)。请你编写一个 SQL 查询,统计学生表中每个班级每次考试的总学生人数(total_num)
select class_id,exam_num,count(id) total_num from student group by class_id ,exam_num;
- 分组查询条件-having
假设有一个学生表 student
,包含以下字段:id
(学号)、name
(姓名)、class_id
(班级编号)、score
(成绩)。请你编写一个 SQL 查询,统计学生表中班级的总成绩超过 150 分的班级编号(class_id)和总成绩(total_score)
select class_id,sum(score) total_score from student group by class_id having sum(score)>150;
- 关联查询-cross join
假设有一个学生表 student
,包含以下字段:id(学号)、name(姓名)、age(年龄)、class_id(班级编号);还有一个班级表 class
,包含以下字段:id(班级编号)、name(班级名称)。
请你编写一个 SQL 查询,将学生表和班级表的所有行组合在一起,并返回学生姓名(student_name)、学生年龄(student_age)、班级编号(class_id)以及班级名称(class_name)
select s.name student_name, s.age student_age, s.class_id class_id, c.name class_name from student s, class c;
- 关联查询-inner join
假设有一个学生表 student
,包含以下字段:id
(学号)、name
(姓名)、age
(年龄)、class_id
(班级编号)。还有一个班级表 class
,包含以下字段:id
(班级编号)、name
(班级名称)、level
(班级级别)。
请你编写一个 SQL 查询,根据学生表和班级表之间的班级编号进行匹配,返回学生姓名(student_name
)、学生年龄(student_age
)、班级编号(class_id
)、班级名称(class_name
)、班级级别(class_level
)
select s.name student_name,s.age student_age,s.class_id class_id,c.name class_name,c.level class_level from student s join class c on s.class_id=c.id;
- 关联查询-outer join
假设有一个学生表 student
,包含以下字段:id
(学号)、name
(姓名)、age
(年龄)、class_id
(班级编号)。还有一个班级表 class
,包含以下字段:id
(班级编号)、name
(班级名称)、level
(班级级别)。
请你编写一个 SQL 查询,根据学生表和班级表之间的班级编号进行匹配,返回学生姓名(student_name
)、学生年龄(student_age
)、班级编号(class_id
)、班级名称(class_name
)、班级级别(class_level
),要求必须返回所有学生的信息(即使对应的班级编号不存在)
select s.name student_name,s.age student_age,s.class_id class_id,c.name class_name,c.level class_level from student s left join class c on s.class_id=c.id;
- 子查询
假设有一个学生表 student
,包含以下字段:id
(学号)、name
(姓名)、age
(年龄)、score
(分数)、class_id
(班级编号)。还有一个班级表 class
,包含以下字段:id
(班级编号)、name
(班级名称)。
请你编写一个 SQL 查询,使用子查询的方式来获取存在对应班级的学生的所有数据,返回学生姓名(name
)、分数(score
)、班级编号(class_id
)字段
select name,score,class_id from student where class_id in (select distinct id from class);
- 子查询-exists
概述:子查询中的一种特殊类型是 “exists” 子查询,用于检查主查询的结果集是否存在满足条件的记录,它返回布尔值(True 或 False),而不返回实际的数据
假设有一个学生表 student
,包含以下字段:id
(学号)、name
(姓名)、age
(年龄)、score
(分数)、class_id
(班级编号)。还有一个班级表 class
,包含以下字段:id
(班级编号)、name
(班级名称)。
请你编写一个 SQL 查询,使用 exists 子查询的方式来获取 不存在对应班级的 学生的所有数据,返回学生姓名(name
)、年龄(age
)、班级编号(class_id
)字段
select name,age,class_id from student where not exists (select class_id from class where class.id = student.class_id);
- 组合查询
假设有一个学生表 student
,包含以下字段:id
(学号)、name
(姓名)、age
(年龄)、score
(分数)、class_id
(班级编号)。还有一个新学生表 student_new
,包含的字段和学生表完全一致。
请编写一条 SQL 语句,获取所有学生表和新学生表的学生姓名(name
)、年龄(age
)、分数(score
)、班级编号(class_id
)字段,要求保留重复的学生记录
select name,age,score,class_id from student
union all
select name,age,score,class_id from student_new;