MySQL数据库(18):高级数据操作-查询数据

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS PostgreSQL,集群系列 2核4GB
简介: MySQL数据库(18):高级数据操作-查询数据

高级数据操作-查询数据

完整的查询指令


select 选项 字段列表 
from 数据源 
-- 5子句
where 条件 
group by 分组 
having 条件 
order by 排序 
limit 限制;

1、select选项

处理查询到的结果


all 默认值,表示保存所有记录

distinct 去重,只保留一条(所有字段都相同认为重复)

create table my_select(
    name varchar(10)
);
insert into my_select (name) values ('A'), ('A'), ('A'), ('B');
mysql> select all * from my_select;
+------+
| name |
+------+
| A    |
| A    |
| A    |
| B    |
+------+
mysql> select distinct * from my_select;
+------+
| name |
+------+
| A    |
| B    |
+------+

2、字段列表

多张表获取数据,可能存在不同表中有同名字段,需要使用别名alias


字段名 [as] 字段别名;
select distinct name as name1, name as name2 from my_select;
+-------+-------+
| name1 | name2 |
+-------+-------+
| A     | A     |
| B     | B     |
+-------+-------+

3、from数据源

为前面的查询提供数据


数据源只要是一个符合二维表结构的数据即可


3.1、单表数据

from 表名;
select * from my_select;

3.2、多表数据

基本语法


from 表名1, 表名2...;
mysql> select * from my_select;
+------+
| name |
+------+
| A    |
| B    |
+------+
2 rows in set (0.00 sec)
mysql> select * from my_student;
+----+--------+
| id | name   |
+----+--------+
|  1 | 刘备   |
|  2 | 李四   |
|  3 | 王五   |
+----+--------+
3 rows in set (0.00 sec)
mysql> select * from my_select, my_student;
+------+----+--------+
| name | id | name   |
+------+----+--------+
| A    |  1 | 刘备   |
| B    |  1 | 刘备   |
| A    |  2 | 李四   |
| B    |  2 | 李四   |
| A    |  3 | 王五   |
| B    |  3 | 王五   |
+------+----+--------+
6 rows in set (0.00 sec)

结果是两张表记录数据相乘,字段数拼接


本质:从第一张表取出一条记录,去拼凑第二张表所有记录,保留所有结果


笛卡尔积,会给数据库造成压力,尽量避免


3.3、动态数据

from后面不是一个实体表,而是一个从表中查询出来得到的二维结果表(子查询)


基本语法


from (select 字段列表 from 表名) as 别名
mysql> select * from (select * from my_student) as t1;
+----+--------+
| id | name   |
+----+--------+
|  1 | 刘备   |
|  2 | 李四   |
|  3 | 王五   |
+----+--------+

4、Where条件

通过运算符进行结果比较,来判断符合条件的数据


5、Group by分组

根据指定的字段,将数据进行分组,分组的目的是为了统计


5.1、分组统计

group by 字段名

分组后,只保留每组的第一条数据


mysql> select * from my_student;
+----+--------+----------+
| id | name   | class_id |
+----+--------+----------+
|  1 | 刘备   |        1 |
|  2 | 李四   |        1 |
|  3 | 王五   |        2 |
+----+--------+----------+
mysql> select  class_id  from my_student group by class_id;
+----------+
| class_id |
+----------+
|        1 |
|        2 |
+----------+

5.2、聚合函数

count() 统计数量。如果是字段,不统计null字段

avg 平均值

sum 求和

max 最大值

min 最小值

group_concat 分组中指定字段拼接

按照班级统计每班人数,最大年龄,最小年龄,平均年龄


mysql> select * from my_student;
+----+--------+----------+------+
| id | name   | class_id | age  |
+----+--------+----------+------+
|  1 | 刘备   |        1 |   18 |
|  2 | 李四   |        1 |   19 |
|  3 | 王五   |        2 |   20 |
+----+--------+----------+------+
mysql> select class_id, count(*), max(age), min(age), avg(age) from my_student group by class_id;
+----------+----------+----------+----------+----------+
| class_id | count(*) | max(age) | min(age) | avg(age) |
+----------+----------+----------+----------+----------+
|        1 |        2 |       19 |       18 |  18.5000 |
|        2 |        1 |       20 |       20 |  20.0000 |
+----------+----------+----------+----------+----------+
mysql> select class_id, group_concat(name), count(*), max(age), min(age), avg(age) from my_student group by class_id;
+----------+--------------------+----------+----------+----------+----------+
| class_id | group_concat(name) | count(*) | max(age) | min(age) | avg(age) |
+----------+--------------------+----------+----------+----------+----------+
|        1 | 刘备,李四          |        2 |       19 |       18 |  18.5000 |
|        2 | 王五               |        1 |       20 |       20 |  20.0000 |
+----------+--------------------+----------+----------+----------+----------+

5.3、多分组

对已分组的数据进行再次分组


基本语法


-- 按照字段1进行分组,将结果再按照字段2进行分组
group by 字段1, 字段2;
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、分组排序

按照分组字段排序,默认升序


-

- 班级升序,性别降序 
-- 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、回溯排序

统计过程中层层上报


group by 字段 with rollup;
-- 分组
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分组之后,可以针对分组数据进行统计筛选


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、单字段排序

基本语法


-- 默认asc升序,desc降序
order by 字段 [asc|desc]
-- 按照年龄降序排序
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、多字段排序

基本语法


order by 字段1, 字段2... [asc|desc];
-- 按照班级和年龄排序
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、记录数限制

基本语法


limit 数量;
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、分页

获取指定区间的数据


基本语法


limit 偏移量, 数量;
-- 等价于
limit 数量 offset 偏移量;

MySQL下标从0开始


分页计算公式:


page: 页数
size: 每页数量
偏移量 = (page - 1) * size
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 |
+----+--------+----------+------+--------+
相关实践学习
如何快速连接云数据库RDS MySQL
本场景介绍如何通过阿里云数据管理服务DMS快速连接云数据库RDS MySQL,然后进行数据表的CRUD操作。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
8天前
|
SQL 存储 运维
从建模到运维:联犀如何完美融入时序数据库 TDengine 实现物联网数据流畅管理
本篇文章是“2024,我想和 TDengine 谈谈”征文活动的三等奖作品。文章从一个具体的业务场景出发,分析了企业在面对海量时序数据时的挑战,并提出了利用 TDengine 高效处理和存储数据的方法,帮助企业解决在数据采集、存储、分析等方面的痛点。通过这篇文章,作者不仅展示了自己对数据处理技术的理解,还进一步阐释了时序数据库在行业中的潜力与应用价值,为读者提供了很多实际的操作思路和技术选型的参考。
21 1
|
12天前
|
存储 Java easyexcel
招行面试:100万级别数据的Excel,如何秒级导入到数据库?
本文由40岁老架构师尼恩撰写,分享了应对招商银行Java后端面试绝命12题的经验。文章详细介绍了如何通过系统化准备,在面试中展示强大的技术实力。针对百万级数据的Excel导入难题,尼恩推荐使用阿里巴巴开源的EasyExcel框架,并结合高性能分片读取、Disruptor队列缓冲和高并发批量写入的架构方案,实现高效的数据处理。此外,文章还提供了完整的代码示例和配置说明,帮助读者快速掌握相关技能。建议读者参考《尼恩Java面试宝典PDF》进行系统化刷题,提升面试竞争力。关注公众号【技术自由圈】可获取更多技术资源和指导。
|
15天前
|
前端开发 JavaScript 数据库
获取数据库中字段的数据作为下拉框选项
获取数据库中字段的数据作为下拉框选项
46 5
|
19天前
|
存储 Oracle 关系型数据库
索引在手,查询无忧:MySQL索引简介
MySQL 是一款广泛使用的关系型数据库管理系统,在2024年5月的DB-Engines排名中得分1084,仅次于Oracle。本文介绍MySQL索引的工作原理和类型,包括B+Tree、Hash、Full-text索引,以及主键、唯一、普通索引等,帮助开发者优化查询性能。索引类似于图书馆的分类系统,能快速定位数据行,极大提高检索效率。
49 8
|
22天前
|
SQL 关系型数据库 MySQL
MySQL 窗口函数详解:分析性查询的强大工具
MySQL 窗口函数从 8.0 版本开始支持,提供了一种灵活的方式处理 SQL 查询中的数据。无需分组即可对行集进行分析,常用于计算排名、累计和、移动平均值等。基本语法包括 `function_name([arguments]) OVER ([PARTITION BY columns] [ORDER BY columns] [frame_clause])`,常见函数有 `ROW_NUMBER()`, `RANK()`, `DENSE_RANK()`, `SUM()`, `AVG()` 等。窗口框架定义了计算聚合值时应包含的行。适用于复杂数据操作和分析报告。
63 11
|
25天前
|
存储 关系型数据库 MySQL
mysql怎么查询longblob类型数据的大小
通过本文的介绍,希望您能深入理解如何查询MySQL中 `LONG BLOB`类型数据的大小,并结合优化技术提升查询性能,以满足实际业务需求。
90 6
|
1月前
|
存储 缓存 网络协议
数据库执行查询请求的过程?
客户端发起TCP连接请求,服务端通过连接器验证主机信息、用户名及密码,验证通过后创建专用进程处理交互。服务端进程缓存以减少创建和销毁线程的开销。后续步骤包括缓存查询(8.0版后移除)、语法解析、查询优化及存储引擎调用,最终返回查询结果。
29 6
|
1月前
|
SQL 关系型数据库 MySQL
mysql分页读取数据重复问题
在服务端开发中,与MySQL数据库进行数据交互时,常因数据量大、网络延迟等因素需分页读取数据。文章介绍了使用`limit`和`offset`参数实现分页的方法,并针对分页过程中可能出现的数据重复问题进行了详细分析,提出了利用时间戳或确保排序规则绝对性等解决方案。
|
1月前
|
SQL JavaScript 程序员
数据库LIKE查询屡试不爽?揭秘大多数人都忽视的秘密操作符!
本文分析了因数据库中的不可见空白字符导致的数据查询问题,探讨了问题的成因与特性,并提出了使用 SQL 语句修复问题的有效方案。同时,总结了避免类似问题的经验和注意事项。
33 0
|
16天前
|
存储 Oracle 关系型数据库
数据库传奇:MySQL创世之父的两千金My、Maria
《数据库传奇:MySQL创世之父的两千金My、Maria》介绍了MySQL的发展历程及其分支MariaDB。MySQL由Michael Widenius等人于1994年创建,现归Oracle所有,广泛应用于阿里巴巴、腾讯等企业。2009年,Widenius因担心Oracle收购影响MySQL的开源性,创建了MariaDB,提供额外功能和改进。维基百科、Google等已逐步替换为MariaDB,以确保更好的性能和社区支持。掌握MariaDB作为备用方案,对未来发展至关重要。
41 3