From 40a0e5ac6eecf8185803a0e153087605b8d0e838 Mon Sep 17 00:00:00 2001 From: pengshiyu <1940607002@qq.com> Date: Tue, 29 Mar 2022 22:50:39 +0800 Subject: [PATCH] fix --- blog/php-mysql/sql-senior-select.md | 289 +++++++++++++++++++++++++++- 1 file changed, 279 insertions(+), 10 deletions(-) diff --git a/blog/php-mysql/sql-senior-select.md b/blog/php-mysql/sql-senior-select.md index f60804c..2c9d4ec 100644 --- a/blog/php-mysql/sql-senior-select.md +++ b/blog/php-mysql/sql-senior-select.md @@ -5,6 +5,8 @@ ```sql select 选项 字段列表 from 数据源 + +-- 5子句 where 条件 group by 分组 having 条件 @@ -12,6 +14,8 @@ order by 排序 limit 限制; ``` + + ## 1、select选项 处理查询到的结果 @@ -155,7 +159,7 @@ mysql> select * from (select * from my_student) as t1; 根据指定的字段,将数据进行分组,分组的目的是为了统计 -## 5.1、分组统计 +### 5.1、分组统计 ```sql group by 字段名 @@ -182,7 +186,7 @@ mysql> select class_id from my_student group by class_id; +----------+ ``` -## 5.2、统计函数(聚合函数) +### 5.2、聚合函数 - count() 统计数量。如果是字段,不统计null字段 - avg 平均值 @@ -221,20 +225,285 @@ mysql> select class_id, group_concat(name), count(*), max(age), min(age), avg(ag +----------+--------------------+----------+----------+----------+----------+ ``` +### 5.3、多分组 + +对已分组的数据进行再次分组 + +基本语法 +```sql +-- 按照字段1进行分组,将结果再按照字段2进行分组 +group by 字段1, 字段2; +``` + +```sql +mysql> select * from my_student; ++----+--------+----------+------+--------+ +| id | name | class_id | age | gender | ++----+--------+----------+------+--------+ +| 1 | 刘备 | 1 | 18 | 2 | +| 2 | 李四 | 1 | 19 | 1 | +| 3 | 王五 | 2 | 20 | 2 | +| 4 | 张飞 | 2 | 21 | 1 | +| 5 | 关羽 | 1 | 22 | 2 | ++----+--------+----------+------+--------+ + +mysql> select class_id, gender, count(*), group_concat(name) from my_student group by class_id, gender; ++----------+--------+----------+--------------------+ +| class_id | gender | count(*) | group_concat(name) | ++----------+--------+----------+--------------------+ +| 1 | 1 | 1 | 李四 | +| 1 | 2 | 2 | 刘备,关羽 | +| 2 | 1 | 1 | 张飞 | +| 2 | 2 | 1 | 王五 | ++----------+--------+----------+--------------------+ +``` -多分组 -分组排序 -回溯统计 +### 5.4、分组排序 +按照分组字段排序,默认升序 +```sql +-- 班级升序,性别降序 +-- mysql8.012之后,不支持group by 排序,需要使用order by排序 +select class_id, gender, count(*), group_concat(name) +from my_student +group by class_id, gender +order by class_id asc, gender desc; ++----------+--------+----------+--------------------+ +| class_id | gender | count(*) | group_concat(name) | ++----------+--------+----------+--------------------+ +| 1 | 2 | 2 | 刘备,关羽 | +| 1 | 1 | 1 | 李四 | +| 2 | 2 | 1 | 王五 | +| 2 | 1 | 1 | 张飞 | ++----------+--------+----------+--------------------+ +``` +### 5.5、回溯排序 -having +统计过程中层层上报 -order -limit +```sql +group by 字段 with rollup; +``` +```sql +-- 分组 +mysql> select class_id, count(*) from my_student group by class_id; ++----------+----------+ +| class_id | count(*) | ++----------+----------+ +| 1 | 3 | +| 2 | 2 | ++----------+----------+ + +-- 分组回溯 +mysql> select class_id, count(*) from my_student group by class_id with rollup; ++----------+----------+ +| class_id | count(*) | ++----------+----------+ +| 1 | 3 | +| 2 | 2 | +| NULL | 5 | ++----------+----------+ + +-- 多分组 +mysql> select class_id, gender, count(*) from my_student group by class_id, gender; ++----------+--------+----------+ +| class_id | gender | count(*) | ++----------+--------+----------+ +| 1 | 2 | 2 | +| 1 | 1 | 1 | +| 2 | 2 | 1 | +| 2 | 1 | 1 | ++----------+--------+----------+ + +-- 多分组回溯 +mysql> select class_id, gender, count(*) from my_student group by class_id, gender with rollup; ++----------+--------+----------+ +| class_id | gender | count(*) | ++----------+--------+----------+ +| 1 | 1 | 1 | +| 1 | 2 | 2 | +| 1 | NULL | 3 | +| 2 | 1 | 1 | +| 2 | 2 | 1 | +| 2 | NULL | 2 | +| NULL | NULL | 5 | ++----------+--------+----------+ +``` + +## 6、having条件 + +和where一样,用来进行数据条件筛选 + +区别: +- where是从表中取数据,where将数据从磁盘拿到内存,where之后的操作都是内存操作 +- having聚合之后的数据中取数据 + +用在group by分组之后,可以针对分组数据进行统计筛选 + +```sql +mysql> select * from my_student; ++----+--------+----------+------+--------+ +| id | name | class_id | age | gender | ++----+--------+----------+------+--------+ +| 1 | 刘备 | 1 | 18 | 2 | +| 2 | 李四 | 1 | 19 | 1 | +| 3 | 王五 | 2 | 20 | 2 | +| 7 | 张飞 | 2 | 21 | 1 | +| 8 | 关羽 | 1 | 22 | 2 | ++----+--------+----------+------+--------+ + + +-- 查询班级人数大于等于3以上的班级 +mysql> select class_id, count(*) as total +from my_student +group by class_id +having total >= 3; ++----------+-------+ +| class_id | total | ++----------+-------+ +| 1 | 3 | ++----------+-------+ +``` + +## 7、order by排序 + +### 7.1、单字段排序 + +基本语法 +```sql +-- 默认asc升序,desc降序 +order by 字段 [asc|desc] +``` + +```sql +-- 按照年龄降序排序 +mysql> select * from my_student order by age asc; ++----+--------+----------+------+--------+ +| id | name | class_id | age | gender | ++----+--------+----------+------+--------+ +| 1 | 刘备 | 1 | 18 | 2 | +| 2 | 李四 | 1 | 19 | 1 | +| 3 | 王五 | 2 | 20 | 2 | +| 7 | 张飞 | 2 | 21 | 1 | +| 8 | 关羽 | 1 | 22 | 2 | ++----+--------+----------+------+--------+ +``` -聚合函数 +### 7.2、多字段排序 +基本语法 +```sql +order by 字段1, 字段2... [asc|desc]; +``` + +```sql +-- 按照班级和年龄排序 +mysql> select * from my_student order by class_id, age desc; ++----+--------+----------+------+--------+ +| id | name | class_id | age | gender | ++----+--------+----------+------+--------+ +| 8 | 关羽 | 1 | 22 | 2 | +| 2 | 李四 | 1 | 19 | 1 | +| 1 | 刘备 | 1 | 18 | 2 | +| 7 | 张飞 | 2 | 21 | 1 | +| 3 | 王五 | 2 | 20 | 2 | ++----+--------+----------+------+--------+ +``` + +## 8、limit 限制 + +限制记录数数量,如果数量不够,仅返回剩余数据 + +### 8.1、记录数限制 + +基本语法 +```sql +limit 数量; +``` + +```sql +mysql> select * from my_student; ++----+--------+----------+------+--------+ +| id | name | class_id | age | gender | ++----+--------+----------+------+--------+ +| 1 | 刘备 | 1 | 18 | 2 | +| 2 | 李四 | 1 | 19 | 1 | +| 3 | 王五 | 2 | 20 | 2 | +| 7 | 张飞 | 2 | 21 | 1 | +| 8 | 关羽 | 1 | 22 | 2 | ++----+--------+----------+------+--------+ + +mysql> select * from my_student limit 2; ++----+--------+----------+------+--------+ +| id | name | class_id | age | gender | ++----+--------+----------+------+--------+ +| 1 | 刘备 | 1 | 18 | 2 | +| 2 | 李四 | 1 | 19 | 1 | ++----+--------+----------+------+--------+ +``` + +### 8.2、分页 + +获取指定区间的数据 + +基本语法 + +```sql +limit 偏移量, 数量; + +-- 等价于 +limit 数量 offset 偏移量; +``` + +MySQL下标从0开始 + +分页计算公式: +``` +page: 页数 +size: 每页数量 + +偏移量 = (page - 1) * size +``` + +```sql +mysql> select * from my_student; ++----+--------+----------+------+--------+ +| id | name | class_id | age | gender | ++----+--------+----------+------+--------+ +| 1 | 刘备 | 1 | 18 | 2 | +| 2 | 李四 | 1 | 19 | 1 | +| 3 | 王五 | 2 | 20 | 2 | +| 7 | 张飞 | 2 | 21 | 1 | +| 8 | 关羽 | 1 | 22 | 2 | ++----+--------+----------+------+--------+ + +-- 每页2条数据,获取第1页 (1 - 1) * 2, 2 +mysql> select * from my_student limit 0, 2; ++----+--------+----------+------+--------+ +| id | name | class_id | age | gender | ++----+--------+----------+------+--------+ +| 1 | 刘备 | 1 | 18 | 2 | +| 2 | 李四 | 1 | 19 | 1 | ++----+--------+----------+------+--------+ + +-- 每页2条数据,获取第2页 (2 - 1) * 2, 2 +mysql> select * from my_student limit 2, 2; ++----+--------+----------+------+--------+ +| id | name | class_id | age | gender | ++----+--------+----------+------+--------+ +| 3 | 王五 | 2 | 20 | 2 | +| 7 | 张飞 | 2 | 21 | 1 | ++----+--------+----------+------+--------+ + +-- 每页3条数据,获取第2页 (3 - 1) * 2, 2 +mysql> select * from my_student limit 4, 2; ++----+--------+----------+------+--------+ +| id | name | class_id | age | gender | ++----+--------+----------+------+--------+ +| 8 | 关羽 | 1 | 22 | 2 | ++----+--------+----------+------+--------+ +``` -https://www.bilibili.com/video/BV1Vx411g7uJ?p=37&spm_id_from=pageDriver \ No newline at end of file +https://www.bilibili.com/video/BV1Vx411g7uJ?p=39&spm_id_from=pageDriver \ No newline at end of file -- GitLab