Mysql数据库-DQL基本查询
- 1 DQL基本查询
- 1.1 基础查询
- 1.2 WHERE子句
- 1)算术运算符
- 2)逻辑运算符
- 3)比较运算符
- A)BETWEEN... AND ...
- B)IN(列表)
- C)NULL值判断
- 4)综合练习
- 2 DQL高级查询
- 2.1 LIKE 模糊查询
- 2.2 AS 别名
- 2.3 ORDER BY排序
- 2.4 LIMIT分页查询
- 1)使用场景
- 2)语法说明
- 3)课堂示例
- 4)综合练习
- 3 聚合操作
- 3.1 聚合函数
- 1)聚合函数示例
- 2)课堂练习
- 3.2 GROUP BY 分组/ORDER BY 排序
- 1)单字段分组
- 2)多字段分组
- 3)分组聚合排序
- 3.3 HAVING子句
- 1)HAVING子句应用
- 2)HAVING和WHERE的区别
- 3.4 DISTINCT去重
- 4 子查询 (SubQuery)
- 1)引言
- 2)应用场景
- 3)子查询分类
- A)单行单列子查询
- B)多行单列子查询
- C)多行多列子查询
1 DQL基本查询
DQL语言用来检索表中数据的语言,涉及到的关键字SELECT
语法
执行顺序
SELECT 子句 6
FROM 子句 1
JOIN... ON...子句 2
WHERE 子句 3
GROUP BY 子句 4
HAVING 子句 5
ORDER BY 子句 7
LIMIT 子句 8
1.1 基础查询
语法
SELECT 字段1,字段2,... FROM 表名;
- SELECT 子句用于指定查询表中的字段
- FROM子句用于指定数据来自那张表
示例
-
查询表中所有字段,以及指定字段
USE tedu; eg1. 检索teacher表中的所有字段的所有记录 SELECT * FROM teacher; eg2. 检索所有老师的id、姓名和年龄 SELECT id,name,age FROM teacher;
注意
实际开发中,java代码若执行DQL语句,**尽量不要用"*" **.
因为当使用SELECT * 时数据库首先要查询数据字典了解待查询表的表结构,了解全字段后才能进行查询。因此会给数据库带来额外的开销,这不划算。因为java代码仅需要编写一次,因此我们应当在SELECT后将所有字段列出。
1.2 WHERE子句
在DQL语句中,WHERE同样用于指定过滤条件,此时仅将满足该过滤条件的记录查询出来
示例
-
查看"一级讲师"的信息,列出:名字,职位,工资,年龄
SELECT name,title,salary,age FROM teacher WHERE title='一级讲师';
-
查看除了"刘苍松"以外的所有老师的名字,工资,奖金,职位
SELECT name,comm,title FROM teacher WHERE name!='刘苍松';
-
查看职位是"大队长"的学生的名字,年龄,性别?
SELECT name,age,gender FROM student WHERE job='大队长';
-
查看年龄在30岁以上(含)的老师的名字,职称,工资,奖金
SELECT name,title,salary,comm FROM teacher WHERE age>=30;
1)算术运算符
eg1:查找年龄为偶数的老师信息
SELECT * FROM teacher
WHERE age%2=0;
eg2:查看年薪高于60000的老师都有谁?
SELECT name,salary
FROM teacher
WHERE salary*12>60000;
2)逻辑运算符
- 逻辑运算符说明
- AND:“与”,都为真时才为真
- OR:“或”,都为假时才为假
-
示例
-
查看7岁的"大队长"都有谁?列出这些学生的名字,年龄,性别和职位
SELECT name,age,gender,job FROM student WHERE age=7 AND job='大队长';
-
查看班级编号小于6的所有中队长都有谁?列明名字,年龄,性别,班级编号(class_id),职位
SELECT name,age,gender,class_id,job FROM student WHERE class_id<6 AND job='中队长';
-
查看所有一级讲师和三级讲师的名字,职称,工资?
SELECT name,title,salary FROM teacher WHERE title='一级讲师' OR title='三级讲师';
-
查看所有大队长,中队长和小队长的名字,性别,年龄和职位?
SELECT name,gender,age,job FROM student WHERE job='大队长' OR job='中队长' OR job='小队长';
-
-
关于
AND
和OR
的优先级AND的优先级高于OR,为了提高OR的优先级,可以使用小括号 “()”
-
查看班级编号在6(含)以下的所有大队长和中队长的名字,年龄,性别,班级编号和职位
SELECT name,age,gender,class_id,job FROM student WHERE class_id<=6 AND job='大队长' OR job='中队长'; # 班级编号在6以下的所有大队长 或者 所有班级的中队长 SELECT name,age,gender,class_id,job FROM student WHERE class_id<=6 AND (job='大队长' OR job='中队长'); # 使用()来提高OR的优先级达到查询需求
-
3)比较运算符
A)BETWEEN… AND …
在一个范围内
示例
-
查看工资在2000到5000之间的老师的名字,性别,年龄,工资
SELECT name,gender,age,salary FROM teacher WHERE salary>=2000 AND salary<=5000; 等价于 SELECT name,gender,age,salary FROM teacher WHERE salary BETWEEN 2000 AND 5000;
-
查看年龄 除了 8到10岁的学生的名字,性别,年龄
SELECT name,gender,age FROM student WHERE age NOT BETWEEN 8 AND 10;
-
查看年龄在20到35之间的男老师都有谁?列出名字,性别,年龄,职称
-
查看所有在3-5层的班级都有哪些?列出班级名称和所在楼层
B)IN(列表)
-
IN(列表):等于列表其中之一
-
NOT IN(列表):不在列表中
示例
-
查看所有大队长,中队长和小队长的名字,性别,年龄和职位?
SELECT name,gender,age,job FROM student WHERE job='大队长' OR job='中队长' OR job='小队长'; 等价于 SELECT name,gender,age,job FROM student WHERE job IN('大队长','中队长','小队长');
-
查看所有一级讲师,二级讲师,三级讲师的名字,职称,工资和性别
SELECT name,title,salary,gender FROM teacher WHERE title IN ('一级讲师','二级讲师','三级讲师');
-
查看除一级讲师和二级讲师之外的所有老师的名字,职称,工资
SELECT name,title,salary FROM teacher WHERE title NOT IN('一级讲师','二级讲师');
-
查看除大队长,中队长,小队长的其他学生的名字,职位,性别,年龄
C)NULL值判断
判断一个字段值是否为NULL
-
IS NULL:判断字段的值是否为NULL
-
IS NOT NULL:判断字段的值是否不是NULL
不可以用 = 和 != 判断NULL值
示例
-
查看哪些老师的奖金为空?
SELECT name,salary,comm FROM teacher WHERE comm IS NULL;
-
查看有奖金的老师?
SELECT name,salary,comm FROM teacher WHERE comm IS NOT NULL;
4)综合练习
- 查看负责课程编号(subject_id)为1的男老师都有谁?
- 查看工资高于5000的女老师都有谁?
- 查看工资高于5000的男老师或所有女老师的工资?
- 查看所有9岁学生的学习委员和语文课代表都是谁?
- 查看工资在6000到10000之间的老师以及具体工资?
- 查看工资在4000到8000以外的老师及具体工资?
- 查看一级讲师和二级讲师的奖金(comm)是多少?
- 查看除老板和总监的其他老师的工资和奖金是多少?
- 查看’3年级2班’和’5年级3班’在那层楼?
#1. 查看负责课程编号(subject_id)为1的男老师都有谁?
SELECT name from teacher where subject_id=1;
#2. 查看工资高于5000的女老师都有谁?
SELECT name from teacher WHERE salary >5000;
#3. 查看工资高于5000的男老师或所有女老师的工资?
SELECT name,salary,gender from teacher WHERE salary >5000 AND gender='男' or gender='女';
#4. 查看所有9岁学生的学习委员和语文课代表都是谁?
SELECT name,age,job from student WHERE age=9 and job='学习委员' or job='语文课代表';
#5. 查看工资在6000到10000之间的老师以及具体工资?
SELECT name,salary from teacher where salary BETWEEN 6000 AND 10000;
#6. 查看工资在4000到8000以外的老师及具体工资?
SELECT name,salary from teacher where salary NOT BETWEEN 4000 AND 8000;
#7. 查看一级讲师和二级讲师的奖金(comm)是多少?
SELECT comm,name,title from teacher WHERE title IN ('一级讲师','二级讲师');
#8. 查看除老板和总监的其他老师的工资和奖金是多少?
SELECT name,salary,comm from teacher where title NOT in('总监','老板');
#9. 查看'3年级2班'和'5年级3班'在那层楼?
SELECT floor,name from class WHERE name IN ('3年级2班','5年级3班');
2 DQL高级查询
2.1 LIKE 模糊查询
LIKE有两个可用的通配符
- _:表示任意一个字符。确切的数量表示1个字符
- %:表示任意个字符。不确切的数量表示0-任意个字符
格式示例
LIKE '%X%' 表示字符串中包含字符X
LIKE '_X%' 表示字符串中第二个字符是X
LIKE 'X%' 表示字符串以X开始
LIKE '%X' 表示字符串以X结束
LIKE '%X_Y' 表示字符串倒数第三个字符数X并且最后一个字符是Y
示例
-
查看名字中含有’苍’的老师都有谁?
SELECT name,title,salary FROM teacher WHERE name LIKE '%苍%';
-
查看姓张的学生都有谁?
-
查看三个字名字中第二个字是’平’的学生都有谁?
-
查看最后一个字是’晶’的老师都有谁?
-
查看哪些学生是课代表?列出他的名字和职位
-
查看所有的2班都在哪层?
#查看姓张的学生都有谁?
SELECT * from student where name like '张%'
#查看三个字名字中第二个字是'平'的学生都有谁?
SELECT * from student where name like '_平_';
#查看最后一个字是'晶'的老师都有谁?
SELECT * from teacher where name like '%晶';
#查看哪些学生是课代表?列出他的名字和职位
SELECT name,job from student WHERE job like '%课代表';
#查看所有的2班都在哪层?
SELECT floor,name from class WHERE name like '%2班';
练习
- 查询名字姓"李"的学生姓名
- 查询名字中包含"江"的学生姓名
- 查询名字以"郭"结尾的学生姓名
- 查询9-12岁里是"课代表"的学生信息
- 查询名字第二个字是"苗"的学生信息
- 查询姓"邱"的课代表都是谁?
#1. 查询名字姓"李"的学生姓名
SELECT * from student where name like '李%';
#2. 查询名字中包含"江"的学生姓名
SELECT * from student where name like '%江%';
#3. 查询名字以"郭"结尾的学生姓名
SELECT * from student where name like '%郭';
#4. 查询9-12岁里是"课代表"的学生信息
SELECT * from student where job like '%课代表' AND age BETWEEN 9 AND 12;
#5. 查询名字第二个字是"苗"的学生信息
SELECT * from student where name like '_苗%';
#6. 查询姓"邱"的课代表都是谁?
SELECT * from student where name like '邱%' AND job like '%课代表';
2.2 AS 别名
语法格式:字段名<空格>别名
别名通常使用在SELECT子句和FROM子句中
- 在SELECT子句中我们可以为字段取别名。
- 当字段为函数或表达式时,我们通常给字段添加别名,为了增加可读性
- 为SELECT中的子查询取别名
- 在FROM 子句中可以为表添加别名
eg1:查询字段重命名
查询所有老师的姓名、工资和年薪
# AS 关键字可以省略不写
SELECT name,salary,salary*12 AS annusal
FROM teacher;
eg2:表重命名
# AS 关键字可以省略不写
SELECT t.name, t.salary, salary*12 AS annusal
FROM teacher AS t;
2.3 ORDER BY排序
ORDER BY子句用于对查询结果集进行排序,可以按照ORDER BY后指定的字段值进行升序或降序排序
-
升序:ORDER BY 字段 [ASC]
将当前结果集按照指定的字段值从小到大排序。
-
降序:ORDER BY 字段 DESC
将当前结果集按照指定的字段值从大到小排序。
-
ORDER BY可以按照多个字段排序,此时排序存在优先级。
- 首先按照ORDER BY后指定的第一个字段的值将结果集按照该字段排序方式(升序或降序)排序
- 排序后再按照第二个字段指定的值排序,仅会对第一个字段值相同的记录按照第二个字段排序
- 若有第三个字段以此类推
-
不指定排序方式时,默认为升序
示例
-
查看老师的工资排名,从多到少
# 将结果集按照salary的降序进行排序 SELECT name,salary FROM teacher ORDER BY salary DESC;
-
查看老师奖金的排名?
SELECT name,comm FROM teacher ORDER BY comm DESC;
-
查看学生的生日,按照从远到近
# 日期是可以比较大小的,规则"远小近大" SELECT name,birth FROM student ORDER BY birth;
-
查看7-10岁的学生信息,学生按照年龄从大到小排序(同年龄的看生日)
SELECT name,age,birth FROM student WHERE age BETWEEN 7 AND 10 ORDER BY birth;
-
查看老师的工资和奖金,首先按照奖金的升序,再按照工资的降序
SELECT name,comm,salary FROM teacher ORDER BY comm ASC,salary DESC; # 每个字段都要单独指定排序方式 多字段排序时,首先将结果集按照comm的排序方式排序,之后将comm字段值相同的记录再按照salary的方式排序 当comm字段值不同的记录,则不会再按照salary字段排序
2.4 LIMIT分页查询
LIMIT 子句用于限制由 SELECT 语句返回的数据数量 或者 UPDATE,DELETE语句的操作数量
1)使用场景
当一条DQL语句可以查询出非常大量的数据时,我们可以分批将数据查询,例如淘宝检索一件商品时,分出现第一页,第二页等信息,每页展示30条记录。一次仅查询30条记录,避免因为数据庞大导致系统过度的资源开销。
2)语法说明
SELECT ...
FROM ...
WHERE ...
ORDER BY ...
LIMIT M,N;
5,5
-
M:表示跳过结果集M条记录
-
N:表示从跳过的M条记录后连续检索N条记录
-
在分页查询中有两个常见的参数
- 页数:当前显示第几页内容
- 条目数:每页显示的条目数
-
分页公式
-
M:(页数-1)*条目数
-
N:条目数
-
例如:显示第3页,每页显示5条记录 M:(3-1)*5 ->M:10 N:5 ->N:5
- 每页显示5条记录,显示第8页数据 :
LIMIT 35,5
- 每页显示20条记录,显示第6页数据:
LIMIT 100,20
- 每页显示5条记录,显示第8页数据 :
-
3)课堂示例
-
查看老师工资的前5名?
SELECT name,salary FROM teacher ORDER BY salary DESC LIMIT 0,5;
-
查看老师奖金信息,按照降序排序后,每页显示3条,显示第5页?
页数:5 条目数:3 - M:(页数-1)*条目数 (5-1)*3->M:12 - N:条目数 SELECT name,comm FROM teacher ORDER BY comm DESC LIMIT 12,3;
4)综合练习
- 查询所有10岁学生的生日,按生日对应的年纪从大到小.
- 查询8岁同学中名字含有"苗"的学生信息
- 查询负责课程编号1和2号且工资高于6000的老师信息
- 查询10岁以上的语文课代表和数学课代表
- 查询不教课程编号1的老师信息,按照工资降序排序
- 查询所有老师的奖金,并按照奖金降序排序
- 查看工资高于8000的老师负责的课程编号都有那些?
- 查看全校年龄最小学生的第11-15名
#1. 查询所有10岁学生的生日,按生日对应的年纪从大到小.
SELECT name,birth from student WHERE age=10 order by birth ASC;
#2. 查询8岁同学中名字含有"苗"的学生信息
SELECT * from student WHERE age=8 AND name like '%苗%';
#3. 查询负责课程编号1和2号且工资高于6000的老师信息
SELECT * from teacher where subject_id IN (1,2) and salary >6000;
#4. 查询10岁以上的语文课代表和数学课代表
SELECT * FROM student WHERE age>10 and job IN ('语文课代表','数学课代表');
#5. 查询不教课程编号1的老师信息,按照工资降序排序
SELECT * from teacher WHERE subject_id=1 order by salary desc;
#6. 查询所有老师的奖金,并按照奖金降序排序
SELECT name,comm from teacher order by comm desc;
#7. 查看工资高于8000的老师负责的课程编号都有那些?
select subject_id,name,salary from teacher where salary >8000;
#8. 查看全校年龄最小学生的第11-15名
select * from student order by age desc limit 10,5;
3 聚合操作
聚合操作指的是在数据查找基础上对数据的进一步整理筛选行为,实际上聚合操作也属于数据的查询筛选范围。
3.1 聚合函数
方法 | 功能 |
---|---|
avg(字段名) | 该字段的平均值 |
max(字段名) | 该字段的最大值 |
min(字段名) | 该字段的最小值 |
sum(字段名) | 该字段所有记录的和 |
count(字段名) | 统计该字段记录的个数 |
-
注意
-
MIN、MAX、SUM、AVG是对值的统计;而COUNT是对记录数的统计
-
聚合函数忽略NULL值;这个在AVG,COUNT上尤为明显
-
1)聚合函数示例
-
查看老师的平均工资是多少?
SELECT AVG(salary) FROM teacher;
-
查看老师的最高工资,最低工资,平均工资和工资总和都是多少?
SELECT MAX(salary),MIN(salary),AVG(salary),SUM(salary) FROM teacher;
-
查看负责课程编号1的老师的平均工资是多少?
SELECT AVG(salary) FROM teacher WHERE subject_id=1;
-
查看总共多少位老师?
SELECT COUNT(name) FROM teacher; # 统计name字段值不为NULL的记录共多少条 SELECT COUNT(comm) FROM teacher; # 因为comm字段有NULL值,聚合函数忽略对NULL的统计 SELECT COUNT(*) FROM teacher; # DBMS基本都对COUNT(*)采取了优化
2)课堂练习
- 查看负责课程编号2的老师共多少人?
- 查看班级编号(class_id)为1的学生有多少人?
- 查看全校学生生日最大的是哪天?
- 查看11岁的课代表总共多少人?
- 姓张的学生有多少人?
- 工资高于5000的老师中最低工资是多少?
- 4层有几个班?
- 老师中"总监"的平均工资是多少?
#1. 查看负责课程编号2的老师共多少人?
SELECT COUNT(*)
FROM teacher WHERE subject_id =2;
#2. 查看班级编号(class_id)为1的学生有多少人?
SELECT COUNT(*) FROM student WHERE class_id =1;
#3. 查看全校学生生日最大的是哪天?
SELECT MIN(birth) FROM student;
#4. 查看11岁的课代表总共多少人?
SELECT COUNT(*) FROM student WHERE age = 11 AND job like '%课代表';
#5. 姓张的学生有多少人?
SELECT COUNT(*) FROM student WHERE name LIKE '张%';
#6. 工资高于5000的老师中最低工资是多少?
SELECT MIN(salary) from teacher WHERE salary >5000;
#7. 4层有几个班?
SELECT COUNT(*) from class WHERE floor = 4;
#8. 老师中"总监"的平均工资是多少?
SELECT AVG(salary) from teacher WHERE title = '总监';
3.2 GROUP BY 分组/ORDER BY 排序
GROUP BY
子句可以将结果集按照指定字段值相同的记录进行分组,配合聚合函数可以实现组内统计。
- 在SELECT子句中出现聚合函数时,那么不在聚合函数中的字段都要出现在GROUP BY子句中。
- GROUP BY子句是配合聚合函数使用的,如果SELECT子句中没有聚合函数,通常不写GROUP BY。
1)单字段分组
示例
-
查看每种职位的老师平均工资是多少?
SELECT AVG(salary),title FROM teacher GROUP BY title;
-
查看每个班级各多少人?
班级号相同的学生应该是同一个班,因此按照班级号相同的记录分组,组内求记录数 SELECT COUNT(*),class_id FROM student GROUP BY class_id;
-
查看学生每种职位各多少人,以及最大生日和最小生日?
SELECT COUNT(*) '人数',MIN(birth) '最大生日',MAX(birth) '最小生日',job FROM student GROUP BY job;
2)多字段分组
GROUP BY后面指定多个字段时,分组方式为:这些字段值都一样的记录看作一组
示例
-
查看同班级同性别的学生分别多少人?
SELECT COUNT(*),class_id,gender FROM student GROUP BY class_id,gender; # 班级号相同且性别相同的记录分为一组
-
查看每个班每种职位各多少人?
SELECT COUNT(*),class_id,job FROM student GROUP BY class_id,job;
3)分组聚合排序
示例
-
查看每个科目老师的平均工资排名?
SELECT AVG(salary) avg_sal,subject_id FROM teacher GROUP BY subject_id ORDER BY avg_sal DESC;
3.3 HAVING子句
HAVING子句用于分组中的过滤条件
示例
-
查看每个科目老师的平均工资?但是仅查看平均工资高于6000的那些.
SELECT AVG(salary),subject_id FROM teacher WHERE AVG(salary)>6000 GROUP BY subject_id;
错误
聚合函数不能在WHERE子句中使用
1)HAVING子句应用
HAVING子句是紧跟在GOURP BY子句之后,用于对分组进行过滤的子句。
2)HAVING和WHERE的区别
-
WHERE是在第一次检索表数据时用于添加过滤条件,确定结果集
-
HAVING是在GROUP BY之后(将结果集分组之后)添加过滤条件的,用于确定分组。
示例
-
查看每个科目老师的平均工资?但是仅查看平局工资高于6000的那些.
子句执行顺序 SELECT AVG(salary),subject_id # 4 符合要求的分组统计对应信息 FROM teacher # 1 数据来源,数据从teacher表查询 GROUP BY subject_id # 2 确定分组,按科目分组(比如6组) HAVING AVG(salary)>6000; # 3 过滤分组,比如只有3组符合要求
-
查看每个科目老师的平均工资,前提是该科目老师最高工资要超过9000
执行顺序 SELECT AVG(salary),subject_id # 4 查看符合要求的分组的统计结果 FROM teacher # 1 确定数据来源 GROUP BY subject_id # 2 确定分成几组 HAVING MAX(salary)>9000; # 3 确定哪些分组符合要求
-
查看各科目男老师的平均工资是多少?前提是该科目老师最低工资高于4000.
SELECT AVG(salary),subject_id FROM teacher WHERE gender='男' GROUP BY subject_id HAVING MIN(salary)>4000;
3.4 DISTINCT去重
DISTINCT可以将结果集按照指定的字段去除重复行;
DISTINCT必须紧跟在SELECT关键字之后。
示例
-
查看老师的职称都有哪些?
SELECT DISTINCT title FROM teacher;
-
查看学生都有哪些职位?
SELECT DISTINCT job FROM student;
-
查看各年龄段的学生都有哪些职位?
SELECT DISTINCT age,job FROM student; 当age与job值相同的记录会被去除。例8岁的大队长可能查出4个,但仅保留一个
4 子查询 (SubQuery)
1)引言
嵌套在一个SQL语句中的DQL语句,该DQL被称为子查询
2)应用场景
- DQL中使用子查询
- 在SELECT子句中,将当前子查询结果作为一个字段展示
- 在WHERE子句中,将当前子查询结果作为过滤条件使用(最常用的场景)
- DML中使用:将一个查询结果集用于增删改操作
3)子查询分类
- 单行单列子查询,该子查询的结果集只有一个值
- 多行单列子查询,该子查询结果集是多个值
- 多行多列子查询,将该子查询当作一张表使用
A)单行单列子查询
示例
-
查看比范传奇工资高的老师都有谁?
1:未知条件:范传奇的工资是多少? SELECT salary FROM teacher WHERE name='范传奇'; # ==>3000 2:谁的工资高于3000? SELECT name,salary FROM teacher WHERE salary>3000; 在数据库中,被嵌套的DQL需要使用()括起来 SELECT name,salary FROM teacher WHERE salary>(SELECT salary FROM teacher WHERE name='范传奇');
-
查看哪些老师的工资是高于平均工资的?
1:未知条件 先查询老师的平均工资是多少? SELECT AVG(salary) FROM teacher; 2:查看高于平均工资 SELECT name,salary FROM teacher WHERE salary>(SELECT AVG(salary) FROM teacher);
-
查看和’李费水’在同一个班的学生都有谁?
SELECT name,class_id FROM student WHERE class_id=(SELECT class_id FROM student WHERE name='李费水');
-
查看工资最高的老师的工资和奖金是多少?
SELECT name,salary,comm FROM teacher WHERE salary=(SELECT MAX(salary) FROM teacher);
B)多行单列子查询
多行单列子查询是可以检索出若干个值。因此作为过滤条件使用时,一般配合:IN,NOT IN使用。
因为等于是不能同时等于好几个值的,只能同于其中之一
示例
-
查看与"祝雷"和"李费水"在同一个班的学生都有谁?
1:未知条件:"祝雷"和"李费水"的班级号是多少 SELECT class_id FROM student WHERE name IN('祝雷','李费水'); 2:查看与他们班级号相同的学生 SELECT name,class_id FROM student WHERE class_id=(SELECT class_id FROM student WHERE name IN('祝雷','李费水'))
错误原因,两个学生的班级号不同,而没有任何一个学生的班级号可以同时等于两个不同的值
SELECT name,class_id FROM student WHERE class_id IN (SELECT class_id FROM student WHERE name IN('祝雷','李费水'))
-
查看比教科目2和科目4老师工资都高的老师都有谁?
SELECT name,salary,subject_id FROM teacher WHERE salary>(SELECT MAX(salary) FROM teacher WHERE subject_id IN(2,4))
C)多行多列子查询
可以将一个查询结果集当作一张表创建出来
示例
-
创建一张表,该表中记录了每个科目老师的工资情况,要求展示:最高,最低,总和和平均工资以及该科目id
CREATE TABLE teacher_salary_info AS SELECT MAX(salary) max_sal,MIN(salary) min_sal, SUM(salary) sum_sal,AVG(salary) avg_sal,subject_id FROM teacher GROUP BY subject_id; 当子查询的SELECT子句包含函数或表达式时,应当为其取别名,此时创建的表中该字段名会使用指定的别名