Java阶段二Day09
文章目录
- Java阶段二Day09
- DQL
- SELECT
- 基础查询
- 全部查询
- `WHERE`子句
- 连接多个条件
- `ORDER BY`子句
- 分页查询
- 在`SELECT`子句中使用函数
- 在`WHERE`中使用表达式
- 别名
- 聚合函数
- 教师总结
- DQL语言-数据查询语言
- 语法
- 基础查询
- 语法
- 例
- WHERE子句
- 例
- 连接多个条件
- 例
- AND的优先级高于OR
- IN(列表)
- 例
- NOT IN(列表)
- BETWEEN... AND ...
- 例
- DISTINCT
- 例
- 综合练习
- 题干
- 答案
- LIKE 模糊查询
- 格式示例
- 例
- 练习
- 题干
- 答案
- NULL值判断
- 例
- ORDER BY子句
- 例
- 分页查询
- 使用场景
- 方言
- 语法
- 例
- 在DQL中使用函数或表达式
- 在SELECT子句中使用表达式
- 例
- 在SELECT子句中使用函数
- IFNULL函数
- 定义
- 作用
- 例
- 在WHERE中使用表达式
- 例
- 在WHERE中使用函数
- 例
- 别名
- 语法
- 综合练习
- 题干
- 答案
- 聚合函数
- 概念
- 聚合函数分类
- 注意事项
- 例
- 练习
- 题干
- 答案
DQL
DQL语言用来检索表中数据的语言,涉及到的关键字SELECT
SELECT
执行顺序:
子句 | 执行顺序 |
---|---|
SELECT 子句 | 6 |
FROM 子句 | 1 |
JOIN… ON…子句 | 2 |
WHERE 子句 | 3 |
GROUP BY 子句 | 4 |
HAVING 子句 | 5 |
ORDER BY 子句 | 7 |
LIMIT 子句 | 8 |
基础查询
- SELECT 子句用于指定查询表中的字段
- FROM子句用于指定数据来自那张表
SELECT 字段1,字段2,... FROM 表名
全部查询
SELECT * FROM 表名
注:实际开发中,执行DQL语句,不要用 *
因为当使用SELECT *
时数据库首先要查询数据字典了解待查询表的表结构,了解全字段后才能进行查询。因此会给数据库带来额外的开销,且不划算。因为java代码仅需要编写一次,因此我们应当在SELECT
后将所有字段列出。
WHERE
子句
在DQL语句中,WHERE
同样用于指定过滤条件,此时仅将满足该过滤条件的记录查询出来
连接多个条件
AND
:“与”,都为真时才为真OR
:“或”,都为假时才为假AND
的优先级高于OR
,为提升OR
的优先级可以使用 “()”IN(列表)
:列表中之一NOT IN(列表)
:不在列表中BETWEEN…AND…
:在一个范围内DISTINCT
:将结果集按照指定字段去除重复行,必须紧跟在SELECT
之后LIKE
:模糊查询,有两个可用通配符,_
表示确切的一个字符,%
表示不确切的0到多个字符(LIKE
不能走索引)NULL
值判断:判断一个字段是否为NULL
,使用IS NULL
判断字段值是否为空,IS NOT NULL
判断字段值是否不是空,不可以使用=
和<>
判断NULL
ORDER BY
子句
ORDER BY
子句用于对查询结果集进行排序,可以按照ORDER BY
后指定的字段值进行升序或降序排序
- 升序:
ORDER BY
字段[ASC]
,将当前结果集按照指定的字段值从小到大排序 - 降序:
ORDER BY
字段DESC
,将当前结果集按照指定的字段值从大到小排序 - ORDER BY可以按照多个字段排序,此时排序存在优先级。首先按照
ORDER BY
后指定的第一个字段的值将结果集按照该字段排序方式(升序或降序)排序。排序后再按照第二个字段指定的值排序,仅会对第一个字段值相同的记录按照第二个字段排序,若有第三个字段以此类推 - 不指定排序方式时,默认为升序
ORDER BY
子句时DQL
中最后一个子句(MySQL 和 MariaDB 还会在ORDER BY
后使用LIMIT
子句,但这属于方言)
分页查询
将一个DQL
语句的查询结果分段查询出来,
分页查询是方言,并没有在SQL92标准中有语法定义。意味着不同的数据库分页方式的SQL可能完全不同,
在ORACLE中使用伪列ROWNUM完成,而MySQL和MariaDB则使用LIMIT子句完成。
SELECT...
FROM...
...
ORDER BY...
LIMIT M,N
# M:表示跳过结果集M条记录,N:表示从跳过的M条记录后连续检索N条记录
# 在分页查询中有两个常见的参数:
# 页数:当前显示第几页内容 条目数:每页显示的条目数
分页公式:M:(页数-1) * 条目数 N:条目数
注意:不添加LIMIT
和添加LIMIT
,有时获取的记录不太一样,是因为MySQL
中,当ORDER BY
列中具有相同的值,则服务器可以自由地以任意顺序返回这些行。解决方式就是在ORDER BY
排序字段相同情况下,在添加一个排序字段,首选ID
在SELECT
子句中使用函数
IFNULL(arg1,arg2)
:当arg1的值不为NULL
时,函数返回arg1的值,当arg1的值为NULL
时,函数返回arg2的值IFNULL
函数的作用就是将一个NULL
值替换为非NULL
值
在WHERE
中使用表达式
别名
别名:通常使用在SELECT
子句和FROM
子句中,增加可读性。使用 AS
(可省略)
- 当字段为函数或表达式时,通常给字段添加别名,增加可读性
- 为
SELECT
中的子查询取别名 - 如果别名希望使用关键字或者别名含有空格时,要使用
“”
将别名括起来
SELECT 字段名 [AS] 别名 FROM 表名
聚合函数
聚合函数:又称为多行函数,分组函数。对记录按照指定字段进行统计,可将多行记录统计出一行记录
MIN
:统计指定字段的最小值MAX
:统计指定字段的最大值SUM
:对指定字段求和AVG
:对指定字段求平均值COUNT
:统计记录数的
注意:MIN
,MAX
,SUM
,AVG
是对值的统计。而COUNT
是对记录数的统计。聚合函数忽略NULL
值。这个在AVG
,COUNT
上尤为明显
教师总结
DQL语言-数据查询语言
DQL语言用来检索表中数据的语言,涉及到的关键字SELECT
语法
执行顺序
SELECT 子句 6
FROM 子句 1
JOIN... ON...子句 2
WHERE 子句 3
GROUP BY 子句 4
HAVING 子句 5
ORDER BY 子句 7
LIMIT 子句 8
基础查询
语法
SELECT 字段1,字段2,... FROM 表名
- SELECT 子句用于指定查询表中的字段
- FROM子句用于指定数据来自那张表
例
-
使用SELECT * FROM 表名,可以从指定的表中查询所有字段
USE tedu 检索teacher表中的所有字段的所有记录 SELECT * FROM teacher
注:
实际开发中,java代码例若执行DQL语句,不要用"*".
因为当使用SELECT * 时数据库首先要查询数据字典了解待查询表的表结构,了解全字段后才能进行查询。因此会给数据库带来额外的开销,者不划算。因为java代码仅需要编写一次,因此我们应当在SELECT后将所有字段列出。
-
查看表中指定的某些字段
查看老师的名字,工资,性别,职位 SELECT name,salary,gender,title FROM teacher
WHERE子句
在DQL语句中,WHERE同样用于指定过滤条件,此时仅将满足该过滤条件的记录查询出来
例
-
查看"一级讲师"的信息,列出:名字,职位,工资,年龄
1:查看老师的相关信息 FROM子句,查看teacher表 2:查看"一级讲师"信息 WHERE子句,添加对应的过滤条件 3:查看名字,职位,工资,年龄 SELECT子句,查看对应的字段 SELECT name,title,salary,age FROM teacher WHERE title='一级讲师'
-
查看除了"刘苍松"以外的所有老师的名字,工资,奖金,职位
SELECT name,salary,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
连接多个条件
- 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
为了提高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的优先级达到查询需求
IN(列表)
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 ('一级讲师','二级讲师','三级讲师')
NOT IN(列表)
IN(列表):不在列表中
-
查看除一级讲师和二级讲师之外的所有老师的名字,职称,工资
SELECT name,title,salary FROM teacher WHERE title<>'一级讲师' AND title<>'二级讲师' 等价于 SELECT name,title,salary FROM teacher WHERE title NOT IN('一级讲师','二级讲师')
-
查看除大队长,中队长,小队长的其他学生的名字,职位,性别,年龄
SELECT name,job,gender,age FROM student WHERE job NOT IN('大队长','中队长','小队长')
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 下限 上限
-
查看年龄在7到10岁的学生的名字,性别,年龄
SELECT name,gender,age FROM student WHERE age BETWEEN 7 AND 10 查看年龄除了8到10岁的学生的名字,性别,年龄 SELECT name,gender,age FROM student WHERE age NOT BETWEEN 8 AND 10
-
查看年龄在20到35之间的男老师都有谁?列出名字,性别,年龄,职称
SELECT name,gender,age,title FROM teacher WHERE age BETWEEN 20 AND 35 AND gender='男'
-
查看所有在3-5层的班级都有哪些?列出班级名称和所在楼层
SELECT name,floor FROM class WHERE floor BETWEEN 3 AND 5
DISTINCT
DISTINCT可以将结果集按照指定的字段去除重复行
DISTINCT必须紧跟在SELECT关键字之后
例
-
查看老师的职称都有哪些?
SELECT title FROM teacher 上述语义时查看teacher表中每个老师的职称 SELECT DISTINCT title FROM teacher
-
查看学生都有哪些职位?
SELECT DISTINCT job FROM student
-
查看各年龄段的学生都有哪些职位?
SELECT DISTINCT age,job 当age与job值相同的记录会被去除。例8岁的大队长可能查出4个,但仅保留 FROM student 一行
综合练习
题干
1.查看负责课程编号(subject_id)为1的男老师都有谁?
2.查看工资高于5000的女老师都有谁?
3.查看工资高于5000的男老师或所有女老师的工资?
4.查看所有9岁学生的学习委员和语文课代表都是谁?
5.查看工资在6000到10000之间的老师以及具体工资?
6.查看工资在4000到8000以外的老师及具体工资?
7.查看老师负责的课程编号都有什么?
8.查看所有女老师的职称都是什么?
9.查看7-10岁的男同学的职位都有哪些?
10.查看一级讲师和二级讲师的奖金(comm)是多少?
11.查看除老板和总监的其他老师的工资和奖金是多少?
12.查看'3年级2班'和'5年级3班'在那层楼?
答案
1.查看负责课程编号(subject_id)为1的男老师都有谁?
SELECT name,gender,subject_id
FROM teacher
WHERE subject_id=1 AND gender='男'
2.查看工资高于5000的女老师都有谁?
SELECT name,salary,gender
FROM teacher
WHERE gender='女' AND 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 job IN('学习委员','语文课代表') AND age=9
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.查看老师负责的课程编号都有什么?
SELECT DISTINCT subject_id
FROM teacher
8.查看所有女老师的职称都是什么?
SELECT DISTINCT title
FROM teacher
WHERE gender='女'
9.查看7-10岁的男同学的职位都有哪些?
SELECT DISTINCT job
FROM student
WHERE age BETWEEN 7 AND 10
AND gender='男'
10.查看一级讲师和二级讲师的奖金(comm)是多少?
SELECT name,title,comm
FROM teacher
WHERE title IN ('一级讲师','二级讲师')
11.查看除老板和总监的其他老师的工资和奖金是多少?
SELECT name,salary,comm
FROM teacher
WHERE title NOT IN('老板','总监')
12.查看'3年级2班'和'5年级3班'在那层楼?
SELECT name,floor
FROM class
WHERE name IN('3年级2班','5年级3班')
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 '%苍%'
-
查看姓张的学生都有谁?
SELECT name,age,gender FROM student WHERE name LIKE '张%'
-
查看三个字名字中第二个字是’平’的学生都有谁?
SELECT name,age,gender FROM student WHERE name LIKE '_平_'
-
查看最后一个字是’晶’的老师都有谁?
SELECT name,gender,age FROM teacher WHERE name LIKE '%晶'
-
查看哪些学生是课代表?列出他的名字和职位
SELECT name,job,age FROM student WHERE job LIKE '%课代表'
-
查看所有的2班都在哪层?
SELECT name,floor FROM class WHERE name LIKE '%2班'
练习
题干
1.查询名字姓"李"的学生姓名
2.查询名字中包含"江"的学生姓名
3.查询名字以"郭"结尾的学生姓名
4.查询9-12岁里是"课代表"的学生信息
5.查询名字第二个字是"苗"的学生信息
6.查询姓"邱"的课代表都是谁?
答案
1.查询名字姓"李"的学生姓名
SELECT name,age,gender
FROM student
WHERE name LIKE '李%'
2.查询名字中包含"江"的学生姓名
SELECT name,age,gender
FROM student
WHERE name LIKE '%江%'
3.查询名字以"郭"结尾的学生姓名
SELECT name,age,gender
FROM student
WHERE name LIKE '%郭'
4.查询9-12岁里是"课代表"的学生信息
SELECT name,age,job
FROM student
WHERE job LIKE '%课代表'
AND age BETWEEN 9 AND 12
5.查询名字第二个字是"苗"的学生信息
SELECT name,age,gender
FROM student
WHERE name LIKE '_苗%'
6.查询姓"邱"的课代表都是谁?
SELECT name,job,age
FROM student
WHERE name LIKE '邱%'
AND job LIKE '%课代表'
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
ORDER BY子句
ORDER BY子句用于对查询结果集进行排序,可以按照ORDER BY后指定的字段值进行升序或降序排序
- 升序:ORDER BY 字段 [ASC]。将当前结果集按照指定的字段值从小到大排序。
- 降序:ORDER BY 字段 DESC。将当前结果集按照指定的字段值从大到小排序。
- ORDER BY可以按照多个字段排序,此时排序存在优先级。
- 首先按照ORDER BY后指定的第一个字段的值将结果集按照该字段排序方式(升序或降序)排序
- 排序后再按照第二个字段指定的值排序,仅会对第一个字段值相同的记录按照第二个字段排序
- 若有第三个字段以此类推
- 不指定排序方式时,默认为升序
- ORDER BY子句是DQL中最后一个子句(像MySQL和MariaDB还会在ORDER BY后使用LIMIT子句,但这属于方言)
例
-
查看老师的工资排名,从多到少
SELECT name,salary FROM teacher ORDER BY salary DESC 将结果集按照salary的降序进行排序
-
查看老师奖金的排名?
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 每个字段都要单独指定排序方式 等同 SELECT name,comm,salary FROM teacher ORDER BY comm ,salary DESC 升序ASC可以忽略 多字段排序时,首先将结果集按照comm的排序方式排序,之后将comm字段值相同的记录再按照salary的方式排序 当comm字段值不同的记录,则不会再按照salary字段排序
分页查询
将一个DQL语句的查询结果分段查询出来
使用场景
当一条DQL语句可以查询出非常大量的数据时,我们可以分批将数据查询,例如淘宝检索一件商品时,分出现第一页,第二页等信息,每页展示30条记录。一次仅查询30条记录,避免因为数据庞大导致系统过度的资源开销,已经更慢的传输速度。
方言
分页查询是方言,并没有在SQL92标准中有语法定义。意味着不同的数据库分页方式的SQL可能完全不同。
在ORACLE中使用伪列ROWNUM完成,而MySQL和MariaDB则使用LIMIT子句完成。
语法
SELECT...
FROM ...
...
ORDER BY ...
LIMIT M,N
-
M:表示跳过结果集M条记录
-
N:表示从跳过的M条记录后连续检索N条记录
-
在分页查询中有两个常见的参数
- 页数:当前显示第几页内容
- 条目数:每页显示的条目数
-
分页公式
-
M:(页数-1)*条目数
-
N:条目数
-
例如:显示第3页,每页显示5条记录 M:(3-1)*5 ->M:10 N:5 ->N:5
-
例
-
查看老师工资的前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
在DQL中使用函数或表达式
在SELECT子句中使用表达式
例
-
查看每个老师的工资和年薪
SELECT name,salary,salary*12 FROM teacher
在SELECT子句中使用函数
IFNULL函数
定义
IFNULL(arg1,arg2)
作用
-
当arg1的值不为NULL时,函数返回arg1的值
-
当arg1的值为NULL时,函数返回arg2的值
-
内部逻辑
用java代码理解内部逻辑 IFNULL(arg1,arg2){ if(arg1!=null){ return arg1; }else{ return arg2; } }
-
IFNULL函数的作用就是将一个NULL值替换为非NULL值
例
-
查看每个老师的工资,奖金,工资+奖金分别是多少?
在数据库中任何数字与NULL运算结果都是NULL SELECT name,salary,comm,salary+comm FROM teacher
SELECT name,salary,comm,salary+IFNULL(comm,0) 使用IFNULL函数将NULL替换为非NULL值 FROM teacher
-
查看每个老师的奖金,以及全年奖金?
SELECT name,comm,IFNULL(comm*12,0) FROM teacher
在WHERE中使用表达式
例
-
查看年薪高于60000的老师都有谁?
SELECT name,salary FROM teacher WHERE salary*12>60000
在WHERE中使用函数
例
-
查看哪些老师的奖金少于3000?
SELECT name,comm FROM teacher WHERE comm<3000 查询不出comm为NULL的记录。因为NUL是状态,不具可比性。因此:=,<>,>,>=,<,<=都不可以 SELECT name,comm FROM teacher WHERE IFNULL(comm,0)<3000
别名
别名通常使用在SELECT子句和FROM子句中
- 在SELECT子句中我们可以为字段取别名。
- 当字段为函数或表达式时,我们通常给字段添加别名,为了增加可读性
- 为SELECT中的子查询取别名
- 在FROM 子句中可以为表添加别名
语法
-
字段名<空格>别名
SELECT name,salary,salary*12 FROM teacher 当SELECT中含有表达式时,结果集该字段使用这个表达式作为字段名
SELECT name,salary,salary*12 annusal FROM teacher
-
字段名 AS 别名
SELECT name,salary,salary*12 AS annusal FROM teacher
-
字段名 [AS] ‘别名’
SELECT name,salary,salary*12 AS 'annusal' FROM teacher SELECT name,salary,salary*12 'annusal' FROM teacher
-
字段名 [AS] “别名”
SELECT name,salary,salary*12 AS "annusal" FROM teacher SELECT name,salary,salary*12 "annusal" FROM teacher
-
如果别名希望使用关键字或者别名含有空格时,要使用引号将别名括起来
SELECT name,salary,salary*12 FROM 希望为salary*12添加别名FROM。此时FROM是关键字 FROM teacher 会引发SQL语义错误 SELECT name,salary,salary*12 'FROM' FROM teacher SELECT name,salary,salary*12 annu sal 当别名中含有空格时,数据库理解为annu是salary*12的 FROM teacher 别名,后面的sal会语法错 误。 SELECT name,salary,salary*12 'annu sal' FROM teacher
综合练习
题干
1.查询所有10岁学生的生日,按生日对应的年纪从大到小.
2.查询8岁同学中名字含有"苗"的学生信息
3.查询负责课程编号1和2号且工资高于6000的老师信息
4.查询10岁以上的语文课代表和数学课代表
5.查询不教课程编号1的老师信息,按照工资降序排序
6.查询没有奖金的老师信息
7.查询所有老师的奖金,并按照奖金降序排序
8.查看工资高于8000的老师负责的课程编号都有那些?
9.查看全校年龄最小学生的第6-10名
答案
1.查询所有10岁学生的生日,按生日对应的年纪从大到小.
SELECT name,age,birth
FROM student
WHERE age=10
ORDER BY birth
2.查询8岁同学中名字含有"苗"的学生信息
SELECT name,age,gender
FROM student
WHERE age=8
AND name LIKE '%苗%'
3.查询负责课程编号1和2号且工资高于6000的老师信息
SELECT name,subject_id,salary
FROM teacher
WHERE subject_id IN (1,2)
AND salary>6000
4.查询10岁以上的语文课代表和数学课代表
SELECT name,age,job
FROM student
WHERE age>10
AND job IN ('语文课代表','数学课代表')
5.查询不教课程编号1的老师信息,按照工资降序排序
SELECT name,subject_id,salary
FROM teacher
WHERE subject_id<>1
ORDER BY salary DESC
6.查询没有奖金的老师信息
SELECT name,comm,salary
FROM teacher
WHERE IFNULL(comm,0)=0
7.查询所有老师的奖金,并按照奖金降序排序
SELECT name,comm
FROM teacher
ORDER BY comm DESC
8.查看工资高于8000的老师负责的课程编号都有那些?
SELECT DISTINCT subject_id
FROM teacher
WHERE salary>8000
9.查看全校年龄最小学生的第6-10名
SELECT name,birth,age
FROM student
ORDER BY birth DESC
LIMIT 5,5
注:第9题,不添加LIMIT看到结果集中6-10和添加了LIMIT获取6-10记录不完全一样
原因:
MySQL官方文档给出了解释
If multiple rows have identical values in the ORDER BY columns, the server is free to return those rows in any order, and may do so differently depending on the overall execution plan. In other words, the sort order of those rows is nondeterministic with respect to the nonordered columns.
One factor that affects the execution plan is LIMIT, so an ORDER BY query with and without LIMIT may return rows in different orders.
翻译:
如果多行在 ORDER BY 列中具有相同的值,则服务器可以自由地以任意顺序返回这些行,并且可能会根据整体执行计划以不同的方式返回这些行。换句话说,这些行的排序顺序对于无序列是不确定的。
影响执行计划的一个因素是 LIMIT,因此带有和不带 LIMIT 的 ORDER BY 查询可能会返回不同顺序的行。
解决方式
解决办法:排序时指定字段值相同的记录无论是否添加LIMIT子句,要保证这些记录的顺序始终一致即可.我们要额外的追加一个辅助字段进行排序,确保顺序一定一致**.通常辅助字段值不要用重复的,赋值字段首选ID**
SELECT name,birth,age
FROM student
ORDER BY birth DESC,id
LIMIT 5,5
查询时当birth字段值相同的记录,在按照id排序,那么birth字段指向相同的记录在结果集中的顺序也一定是一致的
聚合函数
概念
聚合函数又称为多行函数,分组函数。对记录按照指定字段统计的,可以将多行记录统计出一行记录
聚合函数分类
- MIN:统计指定字段的最小值
- MAX:统计指定字段的最大值
- SUM:对指定字段求和
- AVG:对指定字段求平均值
- COUNT:统计记录数的
注意事项
- MIN,MAX,SUM,AVG是对值的统计。而COUNT是对记录数的统计
- 聚合函数忽略NULL值。这个在AVG,COUNT上尤为明显
例
-
查看老师的平均工资是多少?
1:先将参与统计的数据查询出来,确定DQL语句 2:再对该DQL添加聚合函数对结果集统计 1:编写DQL查询出参与统计的记录(所有老师的工资) SELECT salary FROM teacher 2:在上述SQL语句的基础上添加聚合函数 SELECT AVG(salary) FROM teacher
-
查看老师的最高工资,最低工资,平均工资和工资总和都是多少?
1:编写DQL查询出参与统计的记录(所有老师的工资) SELECT salary,salary,salary,salary FROM teacher 2:在上述SQL语句的基础上添加聚合函数 SELECT MAX(salary),MIN(salary),AVG(salary),SUM(salary) FROM teacher
-
查看负责课程编号1的老师的平均工资是多少?
1:准备数据(课程编号1的老师工资) SELECT salary FROM teacher WHERE subject_id=1 2:添加聚合函数 SELECT AVG(salary) FROM teacher WHERE subject_id=1
-
查看总共多少位老师?
1:查询出所有老师 SELECT name FROM teacher 2:添加聚合函数 SELECT COUNT(name) FROM teacher 统计name字段值不为NULL的记录共多少条 SELECT COUNT(comm) FROM teacher 因为comm字段有NULL值,聚合函数忽略对NULL的统计 SELECT COUNT(1) FROM teacher 可以,不推荐 SELECT COUNT(*) FROM teacher DBMS基本都对COUNT(*)采取了优化
练习
题干
1.查看所有老师的平均奖金是多少?
2.查看负责课程编号2的老师共多少人?
3.查看班级编号(class_id)为1的学生有多少人?
4.查看全校学生生日最大的是哪天?
5.查看11岁的课代表总共多少人?
6.姓张的学生有多少人?
7.工资高于5000的老师中最低工资是多少?
8.4层有几个班?
9.老师中"总监"的平均工资是多少?
答案
1.查看所有老师的平均奖金是多少?
2.查看负责课程编号2的老师共多少人?
3.查看班级编号(class_id)为1的学生有多少人?
4.查看全校学生生日最大的是哪天?
5.查看11岁的课代表总共多少人?
6.姓张的学生有多少人?
7.工资高于5000的老师中最低工资是多少?
8.4层有几个班?
9.老师中"总监"的平均工资是多少?