MySQL 分组|排序
Enter password: ****
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.44-log MySQL Community Server (GPL)
Copyright (c) 2000, 2023, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| bms |
| db_com |
| db_test1 |
| lb_db |
| lb_db1 |
| mysql |
| performance_schema |
| sys |
| test1 |
| test3 |
| test5 |
| testdb |
+--------------------+
13 rows in set (0.08 sec)
mysql>
mysql>
mysql>
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| bms |
| db_com |
| db_test1 |
| lb_db |
| lb_db1 |
| mysql |
| performance_schema |
| sys |
| test1 |
| test3 |
| test5 |
| testdb |
+--------------------+
13 rows in set (0.00 sec)
mysql> use testdb;
Database changed
mysql>
mysql> select * form user;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that
corresponds to your MySQL server version for the right syntax to use near 'form
user' at line 1
mysql> select * from user;
+----+--------+------+-------+
| id | name | sex | score |
+----+--------+------+-------+
| 1 | 小明 | 男 | 55 |
| 2 | 小红 | 女 | 72 |
| 3 | 小张 | 男 | 88 |
| 4 | 张三 | 男 | 80 |
| 5 | 李四 | 女 | 40 |
| 6 | 李梅 | 女 | 60 |
| 7 | 小美 | 男 | 99 |
+----+--------+------+-------+
7 rows in set (0.04 sec)
mysql> select avg(score) from user;
+-------------------+
| avg(score) |
+-------------------+
| 70.57142857142857 |
+-------------------+
1 row in set (0.02 sec)
mysql> select count(*) from user;
+----------+
| count(*) |
+----------+
| 7 |
+----------+
1 row in set (0.00 sec)
mysql> select * from user group by sex;
ERROR 1055 (42000): Expression #1 of SELECT list is not in GROUP BY clause and c
ontains nonaggregated column 'testdb.user.id' which is not functionally dependen
t on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_gr
oup_by
mysql> select id,name,sex,score from user group by sex;
ERROR 1055 (42000): Expression #1 of SELECT list is not in GROUP BY clause and c
ontains nonaggregated column 'testdb.user.id' which is not functionally dependen
t on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_gr
oup_by
mysql> select sex from user group by sex;
+------+
| sex |
+------+
| 女 |
| 男 |
+------+
2 rows in set (0.02 sec)
mysql> select sex,avg(score) from user group by sex;
+------+--------------------+
| sex | avg(score) |
+------+--------------------+
| 女 | 57.333333333333336 |
| 男 | 80.5 |
+------+--------------------+
2 rows in set (0.02 sec)
mysql> select sex,avg(score) from user group by sex order by avg(score) desc;
+------+--------------------+
| sex | avg(score) |
+------+--------------------+
| 男 | 80.5 |
| 女 | 57.333333333333336 |
+------+--------------------+
2 rows in set (0.00 sec)
mysql> select * from user order by score desc;
+----+--------+------+-------+
| id | name | sex | score |
+----+--------+------+-------+
| 7 | 小美 | 男 | 99 |
| 3 | 小张 | 男 | 88 |
| 4 | 张三 | 男 | 80 |
| 2 | 小红 | 女 | 72 |
| 6 | 李梅 | 女 | 60 |
| 1 | 小明 | 男 | 55 |
| 5 | 李四 | 女 | 40 |
+----+--------+------+-------+
7 rows in set (0.00 sec)
mysql>
复习
mysql> create database if not exists chapter character set utf8mb4;
Query OK, 1 row affected (0.10 sec)
mysql> use chapter;
Database changed
mysql> create table stdt (id int primary key auto_increment comment '学号',name
char(8) unique comment '姓名',gender char(2) comment '性别',score int comment '
成绩');
Query OK, 0 rows affected (0.40 sec)
mysql> desc stdt;
+--------+---------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------+---------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | char(8) | YES | UNI | NULL | |
| gender | char(2) | YES | | NULL | |
| score | int(11) | YES | | NULL | |
+--------+---------+------+-----+---------+----------------+
4 rows in set (0.04 sec)
mysql> show full columns from stdt\G;
*************************** 1. row ***************************
Field: id
Type: int(11)
Collation: NULL
Null: NO
Key: PRI
Default: NULL
Extra: auto_increment
Privileges: select,insert,update,references
Comment: 学号
*************************** 2. row ***************************
Field: name
Type: char(8)
Collation: utf8mb4_general_ci
Null: YES
Key: UNI
Default: NULL
Extra:
Privileges: select,insert,update,references
Comment: 姓名
*************************** 3. row ***************************
Field: gender
Type: char(2)
Collation: utf8mb4_general_ci
Null: YES
Key:
Default: NULL
Extra:
Privileges: select,insert,update,references
Comment: 性别
*************************** 4. row ***************************
Field: score
Type: int(11)
Collation: NULL
Null: YES
Key:
Default: NULL
Extra:
Privileges: select,insert,update,references
Comment: 成绩
4 rows in set (0.02 sec)
ERROR:
No query specified
mysql> insert into stdt (name,gender,score) values
-> ('张三','男',89),
-> ('赵三','男',95),
-> ('张四','女',76);
Query OK, 3 rows affected (0.09 sec)
Records: 3 Duplicates: 0 Warnings: 0
mysql> insert into stdt (name,gender,score) values
-> ('王五','男',100);
Query OK, 1 row affected (0.01 sec)
mysql> select * from stdt;
+----+--------+--------+-------+
| id | name | gender | score |
+----+--------+--------+-------+
| 1 | 张三 | 男 | 89 |
| 2 | 赵三 | 男 | 95 |
| 3 | 张四 | 女 | 76 |
| 4 | 王五 | 男 | 100 |
+----+--------+--------+-------+
4 rows in set (0.00 sec)
mysql> update stdt set gender='女' where name='王五';
Query OK, 1 row affected (0.06 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> select * from stdt;
+----+--------+--------+-------+
| id | name | gender | score |
+----+--------+--------+-------+
| 1 | 张三 | 男 | 89 |
| 2 | 赵三 | 男 | 95 |
| 3 | 张四 | 女 | 76 |
| 4 | 王五 | 女 | 100 |
+----+--------+--------+-------+
4 rows in set (0.00 sec)
mysql> alter table stdt drop index name;
Query OK, 0 rows affected (0.10 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> desc stdt;
+--------+---------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------+---------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | char(8) | YES | | NULL | |
| gender | char(2) | YES | | NULL | |
| score | int(11) | YES | | NULL | |
+--------+---------+------+-----+---------+----------------+
4 rows in set (0.00 sec)
mysql> alter table stdt change name sname char(8);
Query OK, 0 rows affected (0.06 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> desc stdt;
+--------+---------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------+---------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| sname | char(8) | YES | | NULL | |
| gender | char(2) | YES | | NULL | |
| score | int(11) | YES | | NULL | |
+--------+---------+------+-----+---------+----------------+
4 rows in set (0.00 sec)
mysql> drop table stdt;
Query OK, 0 rows affected (0.07 sec)
mysql> show tables;
Empty set (0.02 sec)
mysql>
在MySQL中,GROUP BY
子句用于将查询结果集按照一个或多个列的值进行分组,以便能对每个组执行聚合操作,如计算总和、平均值、最大值、最小值或计数等。使用 GROUP BY
时,通常会结合聚合函数(如 SUM()
, AVG()
, COUNT()
, MAX()
, MIN()
等)来获取每组的特定统计信息。
基本语法
SELECT column1, aggregate_function(column2)
FROM table_name
WHERE conditions
GROUP BY column1, [column2, ...]
[HAVING conditions];
column1
: 是用于分组的列名,也可以是多个列名,用逗号分隔。aggregate_function(column2)
: 聚合函数应用于分组后的数据,column2
是要进行聚合操作的列。HAVING conditions
: 可选子句,用于过滤聚合后的结果组,类似于WHERE
但作用于分组后的数据。
示例
假设有一个 orders
表,包含 customer_id
(顾客ID)和 order_amount
(订单金额)两个字段,你想按顾客ID分组并计算每个顾客的总订单金额:
SELECT customer_id, SUM(order_amount) AS total_amount
FROM orders
GROUP BY customer_id;
多列分组
如果需要根据多个列进行分组,只需在 GROUP BY
后列出所有列名:
SELECT customer_id, product_category, SUM(order_amount) AS category_total
FROM orders
GROUP BY customer_id, product_category;
这样,结果将首先按 customer_id
分组,然后在每个顾客内部再按 product_category
进一步分组。
使用HAVING
如果你想对分组后的结果进行过滤,比如只显示总金额大于1000的顾客:
SELECT customer_id, SUM(order_amount) AS total_amount
FROM orders
GROUP BY customer_id
HAVING total_amount > 1000;
注意事项
- 分组列应选择那些在逻辑上能够将数据合理划分的列。
- 在使用
HAVING
子句时,不能直接使用未在GROUP BY
中列出的列或聚合函数之外的列。 WHERE
子句用于在分组前过滤行,而HAVING
则是在分组后过滤组。
通过 GROUP BY
,你可以对数据进行高级分析,获得汇总统计数据,这对于报告、数据分析和业务洞察非常有用。
在MySQL中,使用 ORDER BY
子句可以对查询结果按照一个或多个字段进行排序。当需要对多个字段进行排序时,字段之间使用逗号分隔,并且MySQL会按照你指定的顺序依次进行排序。排序规则可以明确指定为 ASC
(升序,默认)或 DESC
(降序)。
基本语法
SELECT column1, column2, ...
FROM table_name
ORDER BY column1 [ASC|DESC], column2 [ASC|DESC], ...
示例
假设有一个 students
表,包含字段 sName
(学生姓名), sAge
(年龄), 和 sGrade
(成绩)。
- 按年龄升序,成绩降序排序:
SELECT * FROM students
ORDER BY sAge ASC, sGrade DESC;
这个查询会首先按照 sAge
字段升序排序所有记录,对于年龄相同的记录,则会按照 sGrade
字段降序排序。
- 只指定第一个字段排序方向:
SELECT * FROM students
ORDER BY sAge DESC, sGrade;
在这个例子中,sAge
会降序排序,而 sGrade
默认升序排序。对于年龄相同的记录,它们会按照成绩升序排列。
- 处理NULL值:
在MySQL中,ORDER BY
处理NULL值时,通常将NULL视为最小值。这意味着,如果某个字段有NULL值,那么NULL值的记录会排在非NULL值的记录之前(在升序排序中),或者之后(在降序排序中)。
注意事项
- 性能考虑: 对大量数据进行多字段排序可能会很慢,特别是如果无法使用索引时。确保排序字段上有合适的索引可以提高性能。
- 短路行为: MySQL在实际执行时,如果第一个排序字段已经能够唯一确定排序结果,那么后面的排序字段将不会起作用。例如,如果
sAge
字段的所有值都是唯一的,那么sGrade
的排序指令将被忽略。 - 明确指定排序方向: 即使默认是升序,也建议明确写出每个字段的排序方向,以增强代码的可读性。
通过合理利用 ORDER BY
子句,你可以灵活地控制查询结果的展示顺序,满足各种业务需求。
MySQL高级查询参见:
MySQL第四章节单表查询.pptx
https://www.alipan.com/s/3F31d12DNok
点击链接保存,或者复制本段内容,打开「阿里云盘」APP ,无需下载极速在线查看,视频原画倍速播放。