【D1n910】(19/42) C++语言程序设计 - MySQL数据库学习笔记 2.4 排序、分组
正常操作,正常分析,大家好,我是D1N910,这是我观看【MySQL数据库】C++语言程序设计 - MySQL数据库:

从而整理的学习笔记。我会继续努力的。
如果你没看过之前的专栏内容,那么强烈建议一定要先看看再继续往下看!






Unit09 where子句
where子句的语法
使用比较运算符
使用SQL提供的运算符
使用逻辑运算符
1. where子句的语法
作用
》根据条件表达式从数据源中筛选符合条件的记录
语法
》select 字段列表
from 数据源
where 条件表达式
2.使用比较运算符
比较运算符
> < >= <= = !=(<>)
示例
》列出考试及格的信息
select * from choose where score>=60;
列出'张三”的考试成绩的信息
运行结果
3.使用SQL提供的运算符
between...and
判断表达式的值是否在给定的闭区间
语法
>表达式 between 值1 and 值2
示例
>列出成绩在70~90之间的信息,等效于 >= 70 and <=90, 闭区间[70, 90]
运行结果
e.g. 列出选课时间是2018年的信息
运行结果
3.2.is null
判断表达式的值是否为null
语法
>表达式 is null
示例
>列出没有班级的学生的信息
>列出没有学生的班级的信息,利用左外连接
可以看到添加了 where s.student_no is null 的是只剩下 student_no is null 的。这个也是检索表中为空的数据的办法。
为什么要用 is null 呢?为什么不能够直接用null判断呢?
观察上面的代码,可以知道,sql 中 null 并不能够直接来进行符号表达式的比对。结果都是 NULL!
那为什么 NULL 值要用 IS 关键字呢?为什么要以这种方式来处理 NULL?
因为,在 SQL 中,NULL 表示“未知”。也就是说,NULL 值表示的是“未知”的值。
NULL = 未知;
在大多数数据库中,NULl 和空字符串是有区别的。
但并不是所有数据库都这样,例如,Oracle 就不支持空字符串,它会把空字符串自动转成 NULL 值。
在其他大多数数据库里,NULL 值和字符串的处理方式是不一样的:
空字符("")串虽然表示“没有值”,但这个值是已知的。
NULL 表示 “未知值”,这个值是未知的。
来源https://www.yii666.com/blog/24808.html
当然,如果是想要找到不为空的,也很简单,加个 not 就行
3.3.in
判断表达式的值是否位于一个列表中,有点“或”的意思。
语法
>表达式 in(值1,值2, ...)
示例
>列出选修了 'C语言' 和 'Java语言’ 的信息,包括学号、课程名称和成绩
3.3、like
判断表达式的值是否符合给定的模式
语法
》 表达式 like '模式'
通配符
》%:匹配任意长度的任意字符
》_:匹配一位任意字符
示例
》列出学生表中姓 '张' 的学生的信息
这里感觉有点正则表达式的意思了🤔
模式中包含通配符
> 示例:列出 information_schema 表中,表名以'user_’开头的表的信息
1. 使用\作为转义字符
2. 自定义转义字符
下面这种更加通用,因为上面的转义字符可能是MySQL专用的,下面这种则很多数据库软件都支持。
escape
v.逃跑;(从监禁或管制中)逃走;逃出;(从不愉快或危险处境中)逃脱;摆脱;逃避;避免(不愉快或危险的事物);逃脱,幸免于难;被忘掉;漏出;(不自觉地)由…发出
n.逃脱;逃避;逃避现实;解脱;消遣;漏出;渗出(量);Esc键
-- 来自百度翻译
4.使用逻辑运算符
用以解决多个条件的问题
4.1、与运算 and
语法
示例1
列出成绩在70~90之间的信息
列出'张三’的成绩信息
运行结果
示例2
使用where子句实现三表内连接
>语法
示例
检索学生的考试成绩信息,列出学号、姓名、选修课程名称和成绩,之前都要 join in
4.2、或运算 or
语法
逻辑表达式1 or 逻辑表达式2
示例
任务:列出选修了’C语言’和’Java语言’的信息,包括学号、课程名称和成绩
这里可以看到用括号吧 or 的包裹起来了
4.3 非运算 not(!)
语法
>not 逻辑表达式 或者!(逻辑表达式)
示例
任务列出选修人数上限不是60的课程的信息
非在MySQl有两种方式,一种是 !,一种是 not
运算符取反

示例
列出有班级的学生的信息
先看 student 表信息
测试 in、not in
如此正常
但是上面的不能和下面一样把 class_no 为 3 的输出
原理
class_no in(1,2,null) ==> class_no=1 or class_no=2 or class_no=null
==> class_no=1 or class_no=2
因为这里是or,所以 class_no=null 可以忽略掉
class_no not in(1,2,null) ==> class_no !=1 and class_no!=2 and class_no!=null
因为是and,而 class_no!=null 也比较不了,所以查出来的都是永不为真的, 得到结果都是不符合条件的。
Unit10 排序&分组
排序
组函数
分组
01、排序
》order by子句
作用
>按照给定的字段或字段列表对结果集进行排序。其中asc从上到下,从小到大;desc从上到下,从大到小。NULL 视为最小值。
语法
其中,
asc: 表示升序排序 缺省方式
desc: 表示降序排序
1、单列排序
结果如下
利用我们之前的exam表,还可以模拟下自己创建数据列的情况
2、多列排序
正常按照升序排序


02、组函数
组函数其实有点像是库函数
常用的组函数
count(expr) 返回 expr 的非空值的数量
max(expr) 返回 expr 的最大值
min(expr) 返回 expr 的最小值
sum(expr) 返回 expr 的累加和
avg(expr) 返回 expr 的平均值
组函数有点像excel的函数
e.g.
得到 choose 中的非空值数量
查看choose_time的最大最小值(这里是时间,所以是最早最晚)
查看student_no为2018001的成绩的总分和平均分
组函数对null值的处理一忽略
e.g. A
可以看到结果里,对于 count 全部的,展示的是 8,但是 count score的,展示的是6.
原因就是因为不考虑 null
e.g. B
组函数的参数可以使用 distinct 修饰
distinct 之前学过,作用是忽略 null!
03.分组
前面我们学的是查所有人的平均分,现在我们想查每个人的平均分应该如何实现呢?
group by子句
group by子句将查询结果按照某个字段(或多个字段)进行分组(字段值相同的
记录作为一个分组),通常与聚合函数一起使用
语法
示例
>统计每一个学生的平均分
结果:
统计每个数据库表的数量
结果:
统计学生总分和平均分
错误提示
分组所能出现的字段
(1)分组字段,即跟随在 group by 之后的字段
(2)组合函数字段,比如sum(组合函数字段)
下面的例子可以展现出(1)、(2)
添加了 course_no 到 group by 之后:
(3)依赖于分组字段的字段
先看下面的 student 表的内容
成功
这里主要是因为分组的字段学号对应的班级号字段只有一个,所以成功了。
如果分组的时候反过来,按照班级分组,然后展示对应的学号,那么又会报错。
原因是因为按照班级分组的时候,因为 s 表中的 class_no 不唯一,所以报错了。
上面是单列分组,下面示范多列分组。
可以看出,分组字段越多,分组也就越多。
现在考虑如何在筛选分组的时候类似 where 再做一层筛选,
比如筛选 information_schema.tables中 cnt 大于50的;
先尝试一下使用 where ,发现失败了。
1、where cnt>50 # where子句中不能使用字段或表达式的别名
原因:因为 where 语句虽然放在了别名语句之后,但是在执行上 where 会比 别名 早,相当于 where 执行的时候,别名 还没取呢!
2、 where count(*)>50 # where子句中不能使用组函数
为了破解上面的问题,我们摸出平替⬇️
having子句
可以对分组子句进行筛选
语法
having 条件表达式
示例
> 列出平均分及格的学生的信息
下面是结果
> 列出表的数量多于50的数据库的信息
除了可以用别名,用 count(*) 也是可以的
下面我们也来看看语法顺序和执行顺序
语法顺序
select
from
where
group by
having
order by
单条语句执行顺序
from(要找到表,所以 from 先执行。因为表命名别名后,整个语句只能用别名,不能用字段的别名)
where(要筛选,用不了字段的别名,所以 where 在 select 前 第二位)
select
(下面的语句都可以用别名,说明他们都在 select 之后)
group by
having(它是对分组结果进行筛选,所以一定是在 group by 后边)
order by(它是对最终结果进行排序,所以一定是在最后面)

恭喜我们,掌握了数据库表的排序、分组
我们的学习进度为 19/42!
未完待续!