ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

MySQL的查询

2026/8/15 6:06:20 拓冰建站 浏览量
MySQL的查询

Mysql的查询

  • 一、基础查询(单表查询)
  • 二、条件查询
    • 1. 比较查询
    • 2. 逻辑查询
    • 3. 范围查询
    • 4. 模糊查询
    • 5. 空值查询
  • 三、排序查询
  • 四、聚合查询
  • 五、分组查询
  • 六、常用函数
    • 1. 聚合函数
    • 2. 字符串函数
      • 长度计算
      • 字符串连接
      • 数字格式化
      • 大小写转换
      • 字符串截取
      • 字符串替换
    • 3. 数值函数
    • 4. 日期时间函数
  • 七、子查询
  • 八、连接查询(多表查询)
    • 1. 交叉连接
    • 2. 内连接
    • 3. 左连接
    • 4. 右连接
    • 5. 全连接
    • 6. 自连接
  • 九、高阶查询
    • 1. 条件聚合
    • 2. 窗口函数
      • 排名函数
      • 聚合运算
  • 总结


一、基础查询(单表查询)

select [distinct] <列名/*> from <表名> [where <条件>] [order by <列名>] [group by 列名]

select 查询
distinct: 去重
from 从哪个表查询
where 条件
order by 排序
group by 分组

  • 表product的字段有pid,pname,price,cid
+-----+-----------------+-------+------+
| pid | pname           | price | cid  |
+-----+-----------------+-------+------+
|   1 | 联想            |  5000 | c001 |
|   2 | 海尔            |  3000 | c001 |
|   3 | 雷神            |  5000 | c001 |
|   4 | 杰克琼斯        |   800 | c002 |
|   5 | 真维斯          |   200 | c002 |
|   6 | 花花公子        |   440 | c002 |
|   7 | 劲霸            |  2000 | c002 |
|   8 | 香奈儿          |   800 | c003 |
|   9 | 相宜本草        |   200 | c003 |
|  10 | 面霸            |     5 | c003 |
|  11 | 好想你枣        |    56 | c004 |
|  12 | 香飘飘奶茶      |     1 | c005 |
|  13 | 海澜之家        |     1 | c002 |
+-----+-----------------+-------+------+

查看所有的商品信息

select * from product;

查看所有商品的商品名和价格

select pname,price from product;

查看所有商品的商品名和价格,列名显示为中文 (取别名)

select pname AS 商品名,price AS 商品价格 from product;
select pname 商品名,price 商品价格 from product;

查看所有商品的商品名和价格*10

select pname 商品名,price*10 10倍价格 from product;

查看商品有哪些类别(去重)

select distinct cid from product;

限制返回数量 limit
limit n => 返回n条数据

select * from product limit 1;

limit n,m => 跳过前n条,输出m条数据

select * from product limit 3,3;

+-----+--------------+-------+------+
| pid | pname        | price | cid  |
+-----+--------------+-------+------+
|   4 | 杰克琼斯     |   800 | c002 |
|   5 | 真维斯       |   200 | c002 |
|   6 | 花花公子     |   440 | c002 |
+-----+--------------+-------+------+

二、条件查询

通过 WHERE 子句指定条件,从表中提取符合条件的记录

1. 比较查询

<,>,<=,>=,!=/<>, =

select * from product where pname=“真维斯”;

+-----+-----------+-------+------+
| pid | pname     | price | cid  |
+-----+-----------+-------+------+
|   5 | 真维斯    |   200 | c002 |
+-----+-----------+-------+------+

名字不等于花花公子的数据

select * from product where pname <> “花花公子”;

单价大于1000的商品

select * from product where price > 1000;


2. 逻辑查询

and or not

单价大于等于200,且小于等于1000

select * from product where price >=200 and price <=1000;

pid小于3或大于10

select * from product where pid<3 or pid >10;

查询分类不等于c004的商品信息

select * from product where not (cid=‘c004’);


3. 范围查询

in 、 between and

单价大于等于200,且小于等于1000

select * from product where price between 200 and 1000;

cid=c001或c003

select * from product where cid in (‘c001’, ‘c003’);
select * from product where cid = ‘c001’ or cid=‘c003’;

not in、not between...and

select * from product where cid not in (‘c001’, ‘c003’);
select * from product where price not between 200 and 1000;


4. 模糊查询

Like (字符串)
% 匹配任意个字符
_ 匹配单个任意字符

select * from product where pname like ‘%家%’;
_ 匹配一个字符
select * from product where pname like ‘海_家’;

  • 正则匹配

regexprlike
默认只要包含即可

select * from product where pname regexp ‘家’;

^ => 以…开头

select * from product where pname rlike ‘^海’;

$ => 以…结尾

select * from product where pname rlike ‘家$’;


5. 空值查询

select * from articles where id is NULL;
select * from articles where id is not NULL;


三、排序查询

order by
默认升序

select * from product order by price;

降序排列

select * from product order by price desc;

多字段排序

select * from product order by cid desc, price desc;

筛选再排序

select * from product where pid between 1 and 10 order by cid desc, price desc;


四、聚合查询

将多条记录聚合到一起计算出一条计算

  • 计数、求和、求平均
  • count(字段名) : 统计值不为NULL的数量

select count(*) from product;
select count(pid) from product;

  • sum(字段): 计算数字的和

select sum(price) from product;

  • max(字段),max: 求最大值,最小值

select max(price),min(price) from product;

  • avg(字段):求平均值

select avg(price) from product;


五、分组查询

…where 条件 group by 列名 [having 条件表达式(having对分组的结果再操作)]

查看每个不同类别的平均值
select list 只能包含group by的字段或聚合函数

select cid,avg(price) from product group by cid;

+------+-------------------+
| cid  | avg(price)        |
+------+-------------------+
| c001 | 4333.333333333333 |
| c002 |             688.2 |
| c003 |               335 |
| c004 |                56 |
| c005 |                 1 |
+------+-------------------+

select cid,price,avg(price) from product group by cid,price;
select cid,price,count(pid) from product group by cid,price;

查找商品类别数量大于等于3的分类

select cid,count(pid) cid_count from product group by cid having cid_count >=3;

+------+-----------+
| cid  | cid_count |
+------+-----------+
| c001 |         3 |
| c002 |         5 |
| c003 |         3 |
+------+-----------+

六、常用函数

1. 聚合函数

将多条数据聚合到一起计算

  • count 不计NULL
  • sum
  • max
  • min
  • avg

2. 字符串函数

长度计算

length => 字符存储消耗的空间
char_length => 统计字符串长度,字符个数

select pname, length(pname), char_length(pname) from product order by pname desc limit 3;

+-----------------+---------------+--------------------+
| pname           | length(pname) | char_length(pname) |
+-----------------+---------------+--------------------+
| 香飘飘奶茶      |            15 |                  5 |
| 香奈儿          |             9 |                  3 |
| 面霸            |             6 |                  2 |
+-----------------+---------------+--------------------+

字符串连接

CONCAT:连接
CONCAT_WS:使用指定的分隔符连接(每个字段)

select concat(cid,‘-’ ,pname) from product;
select concat_ws(‘-’,cid,pname,‘a’,‘b’,‘c’) from product;


数字格式化

FORMAT

root@test 17: 13>select format(3.1415, 3);

+-------------------+
| format(3.1415, 3) |
+-------------------+
| 3.142             |
+-------------------+

大小写转换

LOWER: 转小写
UPPER转大小

select lower(‘Hello’), upper(‘Hello’);

+----------------+----------------+
| lower('Hello') | upper('Hello') |
+----------------+----------------+
| hello          | HELLO          |
+----------------+----------------+

字符串截取

LEFT: 从左取字符串
RIGHT:从右取字符串

select pname, left(pname,2), right(pname,2) from product;

SUBSTRING: 取子串
substring(string, 起始位置,长度)

select substring(pname,2,1) from product;

LTRIM: 删除前导空格(左侧)
RTRIM: 删除后续空格(右侧)
TRIM: 删除指定前导符或后续符

root@test 17: 17>select length(’  Mysql ‘),length(ltrim(’  Mysql ‘)), length(rtrim(’  Mysql '));

+--------------------+---------------------------+---------------------------+
| length('  Mysql ') | length(ltrim('  Mysql ')) | length(rtrim('  Mysql ')) |
+--------------------+---------------------------+---------------------------+
|                  8 |                         6 |                         7 |
+--------------------+---------------------------+---------------------------+

删除左边指定符号

root@test 17: 18>select ‘–Mysql–’,trim(LEADING '-' FROM ‘–Mysql–’);

+-----------+------------------------------------+
| --Mysql-- | trim(LEADING '-' FROM '--Mysql--') |
+-----------+------------------------------------+
| --Mysql-- | Mysql--                            |
+-----------+------------------------------------+
1 row in set (0.00 sec)

删除右边指定符号

root@test 17: 21>select ‘–Mysql–’,trim(TRAILING '-' FROM ‘–Mysql–’);

删除两边指定符号

root@test 17: 21>select ‘–Mysql–’,trim(BOTH '-' FROM ‘–Mysql–’);


字符串替换

REPLACE

select replace(pname, '花','hua') from product;


3. 数值函数

CEIL: 向上取整
FLOOR: 向下取整

SELECT 3.1415, CEIL(3.1415), FLOOR(3.1415);

+--------+--------------+---------------+
| 3.1415 | CEIL(3.1415) | FLOOR(3.1415) |
+--------+--------------+---------------+
| 3.1415 |            4 |             3 |
+--------+--------------+---------------+

DIV : 取整除
MOD: 取余

root@test 17: 29>SELECT 5/2, 5 DIV 2, 5 MOD 2;

+--------+---------+---------+
| 5/2    | 5 DIV 2 | 5 MOD 2 |
+--------+---------+---------+
| 2.5000 |       2 |       1 |
+--------+---------+---------+

ROUND: 四舍五入
POWER: 冪运算

root@test 17: 30>SELECT POWER(2,10),ROUND(3.1425, 3);

+-------------+------------------+
| POWER(2,10) | ROUND(3.1425, 3) |
+-------------+------------------+
|        1024 |            3.143 |
+-------------+------------------+

4. 日期时间函数

NOW: 获取当前日期时间
CRUDATE: 获取当前日期
CURTIME :获取当前时间

select now(), curdate(), curtime();

+---------------------+------------+-----------+
| now()               | curdate()  | curtime() |
+---------------------+------------+-----------+
| 2025-07-04 17:34:18 | 2025-07-04 | 17:34:18  |
+---------------------+------------+-----------+

YEAR(date):提取年份
MONTH(date):提取月份
DAY(date):提取日

select YEAR(now()),month(now()),day(now());
+-------------+--------------+------------+
| YEAR(now()) | month(now()) | day(now()) |
+-------------+--------------+------------+
|        2025 |            7 |         4 |
+-------------+--------------+------------+

DATE_ADD: 日期操作(计算)

root@test 17: 35>select date_add(curdate(), interval 10 day);

+--------------------------------------+
| date_add(curdate(), interval 10 day) |
+--------------------------------------+
| 2025-07-14                           |
+--------------------------------------+
1 row in set (0.00 sec)

root@test 17: 35>select date_add(curdate(), interval -10 day);
root@test 17: 36>select date_add(curdate(), interval 2 year);
root@test 17: 36>select date_add(curdate(), interval 1 week);

DATEDIFF 日期差值

select datediff(‘2025-1-1’, ‘2026-3-4’);

DATE_FORMATE 日期格式化

select date_format(now(), ‘%Y/%m/%d’);


七、子查询

一条select查询语句的结果作为另一条select语句的一部分

select * from (select * from table)
select * from table where id in (select id from table)

子查询的特点:

  1. 子查询必须放在小括号中
  2. 子查询是可以独立存在的语句
  3. 子查询一般有两个位置,充当数据源(表),或充当条件

创建商品表

CREATE TABLE product
(
pid INT PRIMARY KEY,
pname VARCHAR(20) NOT NULL,
price DOUBLE,
cid CHAR(4)
);

创建商品信息表

CREATE TABLE category
(
cid CHAR(4) PRIMARY KEY,
cname VARCHAR(10)
);

表的数据,后续操作基于此表

root@test 22: 39>select * from product;
+-----+-----------------+-------+------+
| pid | pname           | price | cid  |
+-----+-----------------+-------+------+
|   1 | 联想            |  5000 | c001 |
|   2 | 海尔            |  3000 | c001 |
|   3 | 雷神            |  5000 | c001 |
|   4 | 杰克琼斯        |   800 | c002 |
|   5 | 真维斯          |   200 | c002 |
|   6 | 花花公子        |   440 | c002 |
|   7 | 劲霸            |  2000 | c002 |
|   8 | 香奈儿          |   800 | c003 |
|   9 | 相宜本草        |   200 | c003 |
|  10 | 面霸            |     5 | c003 |
|  11 | 好想你枣        |    56 | c004 |
|  12 | 香飘飘奶茶      |     1 | c005 |
|  13 | 海澜之家        |     1 | c002 |
+-----+-----------------+-------+------+root@test 22: 40>select * from category;
+------+-----------+
| cid  | cname     |
+------+-----------+
| c001 | 家电      |
| c002 | 鞋服      |
| c003 | 化妆品    |
| c004 | 箱包      |
| c005 | 食品      |
+------+-----------+

1. 通过子查询的方式,查询出价格最高的商品信息

a. 找出最高的单价

select max(price) from product;

b. 找到价格最高的商品信息

select * from product where price = (select max(price) from product);

2. 查询`化妆品`分类下的商品名称、商品价格

a. 找到`化妆品`的cid

select cid from category where cname=‘化妆品’;

b. 根据cid查询商品信息

select pname,price from product where cid = (select cid from category where cname=‘化妆品’);

3. 查询小于平均价格的商品信息

a. 找到平均价格

select avg(price) from product;

b. 找到商品

select * from product where price < (select avg(price) from product);

4. 查询价格小于2000的商品来自哪些分类(分类名称(化妆品…))
分类名 -> 分类cid -> product

a. 找到小于2000的商品的cid

select distinct cid from product where price <2000;

b. 根据查询的cid找到对应的分类名

select cname from category where cid in (select distinct cid from product where price <2000);

5. 查询`家电`和`鞋服`下的全部商品信息

a. 查询`家电`和`鞋服`的cid

select cid from category where cname=‘家电’ or cname =‘鞋服’;

b. 查询对应cid的商品

select * from product where cid in (select cid from category where cname=‘家电’ or cname =‘鞋服’);


将子查询的结果作为一张表
select 查询字段 from (子查询) as 别名 where 条件

1. 查询商品类别均价大于200的所有商品信息

a. 查询商品类别均价,找到均价大于200的分类

select cid, avg(price) p_avg from product group by cid having p_avg >200;

b. cid列表

select cid from (select cid, avg(price) p_avg from product group by cid having p_avg >200) t1;

c. 从product表中找到对应分类的商品信息

select * from product where cid in (select cid from (select cid, avg(price) p_avg from product group by cid having p_avg >200) t1);

等效写法

select * from product where cid in (select cid from product group by cid having avg(price)>200);


八、连接查询(多表查询)

多表查询需要表与表之间有紧密关联的

创建学生表

root@test 14: 45>select * from student;
+----+--------+------+----------+
| id | name   | age  | class_id |
+----+--------+------+----------+
|  1 | 张三   |   18 |        1 |
|  2 | 李四   |   19 |        2 |
|  3 | 王五   |   20 |        1 |
|  4 | 赵六   |   18 |        2 |
|  5 | 马七   |   20 |        4 |
+----+--------+------+----------+

创建班级表

root@test 14: 45>select * from class;
+----+--------+-----------+
| id | name   | teacher   |
+----+--------+-----------+
|  1 | 一班   | 张老师    |
|  2 | 二班   | 李老师    |
|  3 | 三班   | 刘老师    |
+----+--------+-----------+

1. 交叉连接

select 列名 from 表1, 表2 where ....
select 列名 from 表1 cross join 表2

会生成所有可能的行组合,也被称为笛卡尔积

root@test 14: 45>select * from class,student;

+----+--------+-----------+----+--------+------+----------+
| id | name   | teacher   | id | name   | age  | class_id |
+----+--------+-----------+----+--------+------+----------+
|  3 | 三班   | 刘老师    |  1 | 张三   |   18 |        1 |
|  2 | 二班   | 李老师    |  1 | 张三   |   18 |        1 |
|  1 | 一班   | 张老师    |  1 | 张三   |   18 |        1 |
|  3 | 三班   | 刘老师    |  2 | 李四   |   19 |        2 |
|  2 | 二班   | 李老师    |  2 | 李四   |   19 |        2 |
|  1 | 一班   | 张老师    |  2 | 李四   |   19 |        2 |
|  3 | 三班   | 刘老师    |  3 | 王五   |   20 |        1 |
|  2 | 二班   | 李老师    |  3 | 王五   |   20 |        1 |
|  1 | 一班   | 张老师    |  3 | 王五   |   20 |        1 |
|  3 | 三班   | 刘老师    |  4 | 赵六   |   18 |        2 |
|  2 | 二班   | 李老师    |  4 | 赵六   |   18 |        2 |
|  1 | 一班   | 张老师    |  4 | 赵六   |   18 |        2 |
|  3 | 三班   | 刘老师    |  5 | 马七   |   20 |        4 |
|  2 | 二班   | 李老师    |  5 | 马七   |   20 |        4 |
|  1 | 一班   | 张老师    |  5 | 马七   |   20 |        4 |
+----+--------+-----------+----+--------+------+----------+

root@test 14: 51>select * from class,student where class.id=student.class_id;

+----+--------+-----------+----+--------+------+----------+
| id | name   | teacher   | id | name   | age  | class_id |
+----+--------+-----------+----+--------+------+----------+
|  1 | 一班   | 张老师    |  1 | 张三   |   18 |        1 |
|  2 | 二班   | 李老师    |  2 | 李四   |   19 |        2 |
|  1 | 一班   | 张老师    |  3 | 王五   |   20 |        1 |
|  2 | 二班   | 李老师    |  4 | 赵六   |   18 |        2 |
+----+--------+-----------+----+--------+------+----------+

2. 内连接

INNER JOIN
返回两个表中满足条件的行的组合

select 列名 from 表1 inner join 表2 on 连接条件;

root@test 14: 55>select * from student inner join class on student.class_id=class.id;

+----+--------+------+----------+----+--------+-----------+
| id | name   | age  | class_id | id | name   | teacher   |
+----+--------+------+----------+----+--------+-----------+
|  1 | 张三   |   18 |        1 |  1 | 一班   | 张老师    |
|  2 | 李四   |   19 |        2 |  2 | 二班   | 李老师    |
|  3 | 王五   |   20 |        1 |  1 | 一班   | 张老师    |
|  4 | 赵六   |   18 |        2 |  2 | 二班   | 李老师    |
+----+--------+------+----------+----+--------+-----------+

隐式内连接

root@test 14: 58>select * from class,student where student.class_id=class.id;


3. 左连接

LEFT JOIN
将左表的数据全部查询出来

select * from student left join class on student.class_id = class.id;

+----+--------+------+----------+------+--------+-----------+
| id | name   | age  | class_id | id   | name   | teacher   |
+----+--------+------+----------+------+--------+-----------+
|  1 | 张三   |   18 |        1 |    1 | 一班   | 张老师    |
|  2 | 李四   |   19 |        2 |    2 | 二班   | 李老师    |
|  3 | 王五   |   20 |        1 |    1 | 一班   | 张老师    |
|  4 | 赵六   |   18 |        2 |    2 | 二班   | 李老师    |
|  5 | 马七   |   20 |        4 | NULL | NULL   | NULL      |
+----+--------+------+----------+------+--------+-----------+

4. 右连接

RIGHT JOIN
将右表的数据全部查询出来

select * from student right join class on student.class_id = class.id;

+------+--------+------+----------+----+--------+-----------+
| id   | name   | age  | class_id | id | name   | teacher   |
+------+--------+------+----------+----+--------+-----------+
|    3 | 王五   |   20 |        1 |  1 | 一班   | 张老师    |
|    1 | 张三   |   18 |        1 |  1 | 一班   | 张老师    |
|    4 | 赵六   |   18 |        2 |  2 | 二班   | 李老师    |
|    2 | 李四   |   19 |        2 |  2 | 二班   | 李老师    |
| NULL | NULL   | NULL |     NULL |  3 | 三班   | 刘老师    |
+------+--------+------+----------+----+--------+-----------+

5. 全连接

UNION
左表和右表中的数据全部展示

root@test 15: 14>select * from student left join class on student.class_id = class.id
-> union
-> select * from student right join class on student.class_id = class.id;

+------+--------+------+----------+------+--------+-----------+
| id   | name   | age  | class_id | id   | name   | teacher   |
+------+--------+------+----------+------+--------+-----------+
|    1 | 张三   |   18 |        1 |    1 | 一班   | 张老师    |
|    2 | 李四   |   19 |        2 |    2 | 二班   | 李老师    |
|    3 | 王五   |   20 |        1 |    1 | 一班   | 张老师    |
|    4 | 赵六   |   18 |        2 |    2 | 二班   | 李老师    |
|    5 | 马七   |   20 |        4 | NULL | NULL   | NULL      |
| NULL | NULL   | NULL |     NULL |    3 | 三班   | 刘老师    |
+------+--------+------+----------+------+--------+-----------+

6. 自连接

将一个表与它自身进行连接

创建菜单表

root@test 14: 45>select * from menu;
+----+-----------+--------+
| id | label     | parent |
+----+-----------+--------+
|  1 | 主页      |      0 |
|  2 | 服务      |      0 |
|  3 | 关于      |      0 |
|  4 | 查单词    |      2 |
|  5 | 查成绩    |      2 |
|  6 | 测试      |      3 |
+----+-----------+--------+

root@test 15: 13>select * from menu as a,menu as b where a.id=b.parent;

+----+--------+--------+----+-----------+--------+
| id | label  | parent | id | label     | parent |
+----+--------+--------+----+-----------+--------+
|  2 | 服务   |      0 |  4 | 查单词    |      2 |
|  2 | 服务   |      0 |  5 | 查成绩    |      2 |
|  3 | 关于   |      0 |  6 | 测试      |      3 |
+----+--------+--------+----+-----------+--------+

九、高阶查询

1. 条件聚合

case when -> 加标签/字段
是一个多分支的函数,可以根据条件列表返回多个值

case 表达式
   when 表达式1 then 结果表达式
   when 表达式2 then 结果表达式
   when 表达式3 then 结果表达式
[else 结果表达式]
end as 新字段名

从上到下测试比较,返回第一个匹配的结果,如果没有匹配上返回NULL

创建成绩表

root@test 15: 58>select * from scores;
+--------+--------+--------+--------+--------+--------------+-----------+--------+
| 学号   | 姓名   | 性别   | 班号   | 系号   | 班主任号     | 课程号    | 成绩   |
+--------+--------+--------+--------+--------+--------------+-----------+--------+
| s01    | 张三   | 男     |      1 |      1 |            1 | M01F013   |     80 |
| s02    | 李四   | 女     |      1 |      3 |            1 | M01F011   |     60 |
| s03    | 王五   | 男     |      2 |      2 |            1 | M01F012   |     50 |
| s04    | 马六   | 男     |      1 |      1 |            1 | M01F011   |     80 |
| s05    | 刘七   | 女     |      1 |      2 |            1 | M01F011   |     80 |
| s06    | 朱八   | 男     |      2 |      3 |            1 | M01F012   |     80 |
| s07    | 赵一   | 女     |      2 |      1 |            1 | M01F011   |     70 |
| s08    | 钱二   | 男     |      2 |      3 |            1 | M01F011   |     80 |
| s09    | 孙小   | 女     |      1 |      2 |            1 | M01F012   |     90 |
| s10    | 冯十   | 男     |      2 |      1 |            1 | M01F013   |     80 |
+--------+--------+--------+--------+--------+--------------+-----------+--------+
10 rows in set (0.01 sec)

查询scores信息,将系号变成字段(学号,姓名,性别,系号)

1 => 计算机
2 => 软件工程
3 => 物联网

root@test 15: 59>select 学号,姓名,性别,
-> case 系号
-> when 1 then “计算机”
-> when 2 then “软件工程”
-> when 3 then “物联网”
-> else “其他”
-> end 系号 from scores;

+--------+--------+--------+--------------+
| 学号   | 姓名   | 性别   | 系号         |
+--------+--------+--------+--------------+
| s01    | 张三   | 男     | 计算机       |
| s02    | 李四   | 女     | 物联网       |
| s03    | 王五   | 男     | 软件工程     |
| s04    | 马六   | 男     | 计算机       |
| s05    | 刘七   | 女     | 软件工程     |
| s06    | 朱八   | 男     | 物联网       |
| s07    | 赵一   | 女     | 计算机       |
| s08    | 钱二   | 男     | 物联网       |
| s09    | 孙小   | 女     | 软件工程     |
| s10    | 冯十   | 男     | 计算机       |
+--------+--------+--------+--------------+

定义成绩等级

>=90 => 优
80-89 => 良
70-79 => 中
60-69 => 及格
<60 不及格

root@test 16: 12>select 学号,姓名,课程号,
-> case
-> when 成绩 >=90 then “优”
-> when 成绩 between 80 and 89 then “良”
-> when 成绩 between 70 and 79 then “中”
-> when 成绩 between 60 and 69 then “及格”
-> when 成绩<60 then “不及格”
-> end 等级
-> from scores;

+--------+--------+-----------+-----------+
| 学号   | 姓名   | 课程号    | 等级      |
+--------+--------+-----------+-----------+
| s01    | 张三   | M01F013   | 良        |
| s02    | 李四   | M01F011   | 及格      |
| s03    | 王五   | M01F012   | 不及格    |
| s04    | 马六   | M01F011   | 良        |
| s05    | 刘七   | M01F011   | 良        |
| s06    | 朱八   | M01F012   | 良        |
| s07    | 赵一   | M01F011   | 中        |
| s08    | 钱二   | M01F011   | 良        |
| s09    | 孙小   | M01F012   | 优        |
| s10    | 冯十   | M01F013   | 良        |
+--------+--------+-----------+-----------+

将成绩用等级制表示,统计每个等级人数

root@test 16: 23>select
-> case
-> when 成绩 >=90 then “优”
-> when 成绩 between 80 and 89 then “良”
-> when 成绩 between 70 and 79 then “中”
-> when 成绩 between 60 and 69 then “及格”
-> when 成绩<60 then “不及格”
-> end 等级,count(*) 人数
-> from scores
-> group by 等级;

+-----------+--------+
| 等级      | 人数   |
+-----------+--------+
| 良        |      6 |
| 及格      |      1 |
| 不及格    |      1 |
| 中        |      1 |
| 优        |      1 |
+-----------+--------+

统计每班男生、女生数量

root@test 16: 33>select 班号, count(case when 性别=“男” then “xxx” end) 男生数, count(case when 性别=“女” then “xxx” end) 女生数 from scores group by 班号;

+--------+-----------+-----------+
| 班号   | 男生数    | 女生数    |
+--------+-----------+-----------+
|      1 |         2 |         3 |
|      2 |         4 |         1 |
+--------+-----------+-----------+

2. 窗口函数

窗口函数是一种在查询结果集上进行计算的一个函数
可以不改变查询结果,为每行添加(排名或聚合信息)

<窗口函数> over (partition by <分组列> order by <排序列>) as 别名
partition by和order by都是可选项

尽量使用别名,直接使用会导致结果列名冗长且难以理解

排名函数

rank(): 排名,如果有值相同,会出现排名空缺 (1,1,3)
dense_rank(): 排名,如果有值相同,不会出现排名空缺 (1,1,2)
row_number(): 排名,如果有值相同,数值连续(1,2,3)

将学生成绩进行排名

  1. rank()

root@test 17: 13>select 班号,学号,姓名,成绩, rank() over (partition by 班号 order by 成绩 desc) 排名 from scores;

+--------+--------+--------+--------+--------+
| 班号   | 学号   | 姓名   | 成绩   | 排名   |
+--------+--------+--------+--------+--------+
|      1 | s09    | 孙小   |     90 |      1 |
|      1 | s01    | 张三   |     80 |      2 |
|      1 | s04    | 马六   |     80 |      2 |
|      1 | s05    | 刘七   |     80 |      2 |
|      1 | s02    | 李四   |     60 |      5 |
|      2 | s06    | 朱八   |     80 |      1 |
|      2 | s08    | 钱二   |     80 |      1 |
|      2 | s10    | 冯十   |     80 |      1 |
|      2 | s07    | 赵一   |     70 |      4 |
|      2 | s03    | 王五   |     50 |      5 |
+--------+--------+--------+--------+--------+
  1. dense_rank()

select 学号,姓名,成绩, dense_rank() over (order by 成绩 desc) 排名 from scores;

  1. row_number()

select 学号,姓名,成绩, row_number() over (order by 成绩 desc) 排名 from scores;


聚合运算

AVG()
SUM()
MAX()
MIN()

展示所有学生信息并展示每班平均分

root@test 17: 21>select 班号,学号,姓名,成绩, avg(成绩) over (partition by 班号) as 班级平均分 from scores;

+--------+--------+--------+--------+-----------------+
| 班号   | 学号   | 姓名   | 成绩   | 班级平均分      |
+--------+--------+--------+--------+-----------------+
|      1 | s01    | 张三   |     80 |              78 |
|      1 | s02    | 李四   |     60 |              78 |
|      1 | s04    | 马六   |     80 |              78 |
|      1 | s05    | 刘七   |     80 |              78 |
|      1 | s09    | 孙小   |     90 |              78 |
|      2 | s03    | 王五   |     50 |              72 |
|      2 | s06    | 朱八   |     80 |              72 |
|      2 | s07    | 赵一   |     70 |              72 |
|      2 | s08    | 钱二   |     80 |              72 |
|      2 | s10    | 冯十   |     80 |              72 |
+--------+--------+--------+--------+-----------------+

总结

MySQL 查询的核心作用是从数据库中高效、精准地获取、处理、分析数据,既是数据交互的基础工具,也是支撑业务逻辑、决策分析的关键手段。

其灵活性(支持简单到复杂的各类场景)和高效性(通过索引等优化)使其成为数据库操作中不可或缺的部分