数据库系列主要介绍工作和学习中遇到的一些问题,以下举例介绍:
假设有个学生成绩表 grade, 有4列:id 主键标识列,学生姓名 student, 课程course, 考试成绩 score, 表数据如下:
id | student | course | score |
1 | 张三 | 英语 | 70 |
2 | 李四 | 英语 | 81 |
3 | 王五 | 英语 | 60 |
4 | 赵六 | 英语 | 90 |
5 | 张三 | 测试 | 50 |
6 | 王五 | 测试 | 75 |
7 | 张三 | 开发 | 80 |
8 | 王五 | 开发 | 90 |
9 | 赵六 | 开发 | 85 |
10 | 张三 | 数学 | 85 |
11 | 王五 | 数学 | 70 |
1.如果我们想要查询所有课程成绩都大于80分的学生姓名,应该怎么查询?
2.如果我们想要查询选择课程数量大于或等于2的学生姓名,应该怎么查询?
解决思路:
一、创建表格
create table grade (
id int identity(1,1),
student varchar(20),
course varchar(20),
score int
);
二、插入数据
insert into grade values('张三','英语',70);
insert into grade values('李四','英语',81);
insert into grade values('王五','英语',60);
insert into grade values('赵六','英语',90);
insert into grade values('张三','测试',50);
insert into grade values('王五','测试',75);
insert into grade values('张三','开发',80);
insert into grade values('王五','开发',90);
insert into grade values('赵六','开发',85);
insert into grade values('张三','数学',85);
insert into grade values('王五','数学',70);
三、查询数据
问题1.分析:查询的是学生姓名student,条件是每科的考试分数都大于80分。
我们可以逆向考虑,查询分数小于等于80分的学生姓名
select distinct student from grade where score<=80
因为学生有多门课程,当学生多门课程的分数满足条件时,会出现重复数据,通过distinct关键词过滤重复数据
只要有一门课程的分数小于等于80,就是我们要排除的数据,所以我们可以通过联合查询方式差集except进行排除。
查询所有不重复学生记录:
select distinct student from grade;
差集查询:
select distinct student from grade
except
select distinct student from grade where score<=80;
其实except关键词已经有去除重复数据的功能,所以最终可以优化为:
select student from grade
except
select student from grade where score<=80;
如果我不想用差集去查询,是否还有其他方法呢?其实思路是一样的,先查询出分数小于等于80分的学生姓名,然后再排除:
select distinct student from grade where student not in (select student from grade where score<=80);
select student from grade group by student having student not in (select student from grade where score<=80);
select student from grade where student not in (select student from grade where score<=80) group by student;
第二条和第三条查询语句结果是一样的,但是having和where还是有区别,having是分组后筛选,而where是筛选后再分组。
问题2.分析:查询的是学生姓名student,条件是考试的课程大于等于2。
我们知道这里student和course组合是唯一的,所以可以通过对student进行分组,查询到每个学生的课程数量:
select student,COUNT(*) as 课程数量 from grade group by student;
然后可以对分组后的数据列表进行筛选,关键词having
select student from grade group by student having COUNT(*)>=2;
这篇文章主要学习了联合查询中的差集except(oracle数据库是minus),not in 排除方法以及分组group by和分组后筛选having.