04_数据查询操作
数据查询语言(核心)
create database test1;
use test1;
-- 数据准备
CREATE TABLE tb_product
(
pid INT PRIMARY KEY auto_increment comment '产品id编号',
pname VARCHAR(20) comment '产品名称',
price int comment '产品价格',
category_id VARCHAR(32) comment '产品所属分类编号(c001电子产品,c002服装)'
);
-- 插入数据
INSERT INTO tb_product VALUES (1,'联想',5000,'c001');
INSERT INTO tb_product VALUES (2,'海尔',3000,'c001');
INSERT INTO tb_product VALUES (3,'雷神',5000,'c001');
INSERT INTO tb_product VALUES (4,'杰克琼斯',800,'c002');
INSERT INTO tb_product VALUES (5,'真维斯',200,'c002');
INSERT INTO tb_product VALUES (6,'花花公子',440,'c002');
INSERT INTO tb_product VALUES (7,'劲霸',2000,'c002');
INSERT INTO tb_product VALUES (8,'香奈儿',800,'c003');
INSERT INTO tb_product VALUES (9,'相宜本草',200,'c003');
INSERT INTO tb_product VALUES (10,'面霸',10,'c003');
INSERT INTO tb_product VALUES (11,'好想你枣',5,'c004');
INSERT INTO tb_product VALUES (12,'香飘飘奶茶',10,'c005');
INSERT INTO tb_product VALUES (13,'海澜之家',200,'c002');
INSERT INTO tb_product VALUES (14,'男人之家',200,'c003');
INSERT INTO tb_product VALUES (15,'男人之家',200);
------------------------------------ Linux中导入数据的方式
1. 进入到数据库中,创建对应的数据库
root@localhost [(none)]> create database test2;
Query OK, 1 row affected (0.01 sec)
2.在服务器中有创建表和插入表中的数据文件 db.sql
[root@node3 /data]# vi db.sql
-- 内容就是上面所提供的
3. 通过mysql命令导入
[root@node3 /data]# mysql -uroot -pAa123456. test2 </data/db.sql 2>/dev/null
4.创建用户和授权
root@localhost [(none)]> create user 'test2'@'%' identified by 'test2';
Query OK, 0 rows affected (0.01 sec)
root@localhost [(none)]> grant select on test2.* to 'test2'@'%';
Query OK, 0 rows affected (0.00 sec)
root@localhost [(none)]> flush privileges;
Query OK, 0 rows affected (0.00 sec)命令作用:
- 这条命令用于打开并编辑文件。进入编辑器后需要保存退出,修改才会写回文件。
- 使用
mysql客户端连接数据库并执行 SQL 或客户端命令。
执行结果:
- 编辑器会打开目标文件;保存并退出后文件内容才会改变。
- 成功后客户端会连接目标服务并执行指定操作;失败时检查地址、端口、用户、密码和数据库名称。
关键参数:
注意事项:
+-----+-----------------+-------+-------------+ +-----+-----------------+-------+-------------+ | 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 | 面霸 | 10 | c003 | | 11 | 好想你枣 | 5 | c004 | | 12 | 香飘飘奶茶 | 10 | c005 | | 13 | 海澜之家 | 200 | c002 | | 14 | 男人之家 | 200 | c003 | +-----+-----------------+-------+-------------+
+-----------------+-------+ +-----------------+-------+ | 联想 | 5000 | | 海尔 | 3000 | | 雷神 | 5000 | | 杰克琼斯 | 800 | | 真维斯 | 200 | | 花花公子 | 440 | | 劲霸 | 2000 | | 香奈儿 | 800 | | 相宜本草 | 200 | | 面霸 | 10 | | 好想你枣 | 5 | | 香飘飘奶茶 | 10 | | 海澜之家 | 200 | | 男人之家 | 200 | +-----------------+-------+
+-----------------+--------+ | 商品名称 | 价格 | +-----------------+--------+ | 联想 | 5000 | | 海尔 | 3000 | | 雷神 | 5000 | | 杰克琼斯 | 800 | | 真维斯 | 200 | | 花花公子 | 440 | | 劲霸 | 2000 | | 香奈儿 | 800 | | 相宜本草 | 200 | | 面霸 | 10 | | 好想你枣 | 5 | | 香飘飘奶茶 | 10 | | 海澜之家 | 200 | | 男人之家 | 200 | +-----------------+--------+
+-----------------+----------+ +-----------------+----------+ | 联想 | 5010 | | 海尔 | 3010 | | 雷神 | 5010 | | 杰克琼斯 | 810 | | 真维斯 | 210 | | 花花公子 | 450 | | 劲霸 | 2010 | | 香奈儿 | 810 | | 相宜本草 | 210 | | 面霸 | 20 | | 好想你枣 | 15 | | 香飘飘奶茶 | 20 | | 海澜之家 | 210 | | 男人之家 | 210 | +-----------------+----------+
+-----------------+-------+ +-----------------+-------+ | 联想 | 5010 | | 海尔 | 3010 | | 雷神 | 5010 | | 杰克琼斯 | 810 | | 真维斯 | 210 | | 花花公子 | 450 | | 劲霸 | 2010 | | 香奈儿 | 810 | | 相宜本草 | 210 | | 面霸 | 20 | | 好想你枣 | 15 | | 香飘飘奶茶 | 20 | | 海澜之家 | 210 | | 男人之家 | 210 | +-----------------+-------+
+-------------+ +-------------+ +-------------+
**语法**条件判断
| 分类 | 运算符 | 说明 | 示例 |
|---|---|---|---|
| 比较运算 | = | 等于 | age = 18 |
!= 或<> | 不等于 | age != 20 | |
>、<、>=、<= | 大于、小于、大于等于、小于等于 | score >= 90 | |
| 范围 | BETWEEN ... AND ... | 在区间范围内(包含两端) | score BETWEEN 60 AND 100 |
| 集合 | IN (...) | 在集合中 | age IN (18, 20, 22) |
| NOT IN (...) | 不在集合中 | age NOT IN (18, 20) | |
| 模糊匹配 | LIKE | 模糊匹配字符串(搜索的意思) <br/>% 代表零个或多个任意字符, <br/>_ 代表一个字符 | name LIKE '张%' <br/>name like '_为' |
| 空值 | IS NULL | 值为空 | address IS NULL |
| IS NOT NULL | 值不为空 | address IS NOT NULL | |
| 逻辑运算 | AND | 并且(与) | age > 18 AND gender='F' |
OR | 或者(或) | age < 18 OR gender='F' | |
| NOT | 取反(非) | NOT age > 18 |
语法:
此like尽量不要出现的你维护的mysql服务中,在现在的工作中,搜索一般都会用第3方搜索引擎来完成,例:Elasticsearch
匹配条件有两个符号:%任意多个任意字符,\_只匹配任意某1个字符
);
+------+--------+--------+
+------+--------+--------+
| 1 | 张三 | 先生 |
| 2 | 晓红 | 女士 |
| 3 | 李四 | 先生 |
+------+--------+--------+
语法如下:+------------------------+ | left('你好世界',2) | +------------------------+ | 你好 | +------------------------+
+------------------------+
+------------------------+
+------------------------++----------------------+ | substr('aabbcc',3,2) | +----------------------+ +----------------------+
按某列数据进行聚合处理
今天我们学习如下聚合函数:
| 聚合函数 | 作用 |
|---|---|
| count() | 统计指定列不为NULL的记录行数;count(*) |
| sum() | 计算指定列的数值和,如果指定列类型不是数值类型,则计算结果为0 |
| max() | 计算指定列的最大值,如果指定列是字符串类型,使用字符串排序运算; |
| min() | 计算指定列的最小值,如果指定列是字符串类型,使用字符串排序运算; |
| avg() | 计算指定列的平均值,如果指定列类型不是数值类型,则计算结果为0 |
);
+-------+ +-------+ | 4 | +-------+
+-------+ +-------+ | 3 | +-------+
**分组查询**就是把一堆数据,按照某个共同的特征(比如部门、性别、地区、年份等)**分成若干组**,然后**对每一组进行统计或汇总**
比如算总数、平均值、最大值等。
**举个生活中的例子:**
假设你是一家公司的HR,手里有一张员工工资表。你想知道**每个部门的平均工资**。
结果可能是:
>
分组字段,
聚合函数(统计字段));
+--------+----------+--------------------+
+--------+----------+--------------------+
+--------+----------+--------------------+
having作用和where类似都是过滤数据的,但是两者之间的执行顺序不同
| 对比项 | `WHERE` | `HAVING` |
|---|---|---|
| **作用时机** | **分组前**过滤原始数据 | **分组后**过滤聚合结果 |
| **能否用聚合函数** | ❌ 不能(如 `COUNT()`, `AVG()`) | ✅ 能 |
| **适用对象** | 单行数据(每一条记录) | 分组后的“组”(每组一条汇总记录) |
| **执行顺序** | 在 `GROUP BY` 之前执行 | 在 `GROUP BY` 之后执行 |
限制查询:主要限制数据查询的数量(获取数据表中的前3条数据)
偏移量:索引下标,默认从0开始
分页查询

在SQL语句中,数据表与数据表之间,如果存在关系,一般一共有3种情况:
比如有A、B两张表,A表中的每一条数据,在B表中有一条唯一的数据与之对应。
| user_id(用户编号) | 账号username | 密码password |
|---|---|---|
| 001 | admin | admin888 |
| 002 | itheima | 123456 |
| user_id(用户编号) | 真实姓名 | 年龄 | 联系方式 |
|---|---|---|---|
| 001 | 张三 | 16 | 10086 |
| 002 | 李四 | 18 | 10010 |
我们把用户表与用户详情表之间的关系就称之为一对一关系。

比如有A、B两张表,A表中的每一条数据,在B表中都有多条数据与之对应,我们把这种关系就称之为一对多关系
产品分类表
| 分类id编号 | 分类名称 |
|---|---|
| 1 | 手机 |
| 2 | 电脑 |
产品信息表
| 产品id编号 | 产品名称 | 产品价格 | 所属分类id编号 |
|---|---|---|---|
| 1 | Apple iPhone 13 | 6799.00 | 1 |
| 2 | Redmi Note 9 | 3499.00 | 1 |
我们把产品分类表与产品表之间的(分类id的对应)关系就称之为一对多关系。

用户表
| 用户编号 | 登录账号 | 登录密码 |
|---|---|---|
| 1 | admin | admin888 |
| 2 | itheima | 123456 |
权限表
| 权限id编号 | 权限名称 |
|---|---|
| 1 | 增加 |
| 2 | 删除 |
| 3 | 修改 |
| 4 | 查询 |

连接查询可以实现多个表的查询,当查询的字段数据来自不同的表就可以使用连接查询来完成。
连接查询可以分为:
准备数据集:
);
(4,'Shell');
);
( );
(2,'bbbbbb');
笛卡尔积连接,没有意义,但是它是所有连接的基础。其功能就是将表1和表2中的每一条数据进行连接。
结果:
查询两个表中符合条件的共有记录

说明:
例1:使用内连接查询学生表与班级表,查询每个学生对应的具体班级信息。
**小结**
以左表为主根据条件查询右表数据,如果根据条件查询右表数据不存在,使用null值填充
商品分类表
| 编号 | 分类名称 |
|---|---|
| 1 | 手机 |
| 2 | 电脑 |
商品表
| 编号 | 商品名称 | 商品分类编号 |
|---|---|---|
| 1 | Vivo手机 | 1 |
| 2 | Xiaomi手机 | 1 |
| 编号 | 分类名称 | 编号 | 商品名称 | 商品分类编号 |
|---|---|---|---|---|
| 1 | 手机 | 1 | Vivo手机 | 1 |
| 1 | 手机 | 2 | Xiaomi手机 | 1 |
| 2 | 电脑 | null | null | null |
左外连接默认会保留左表,然后与右边的表进行匹配;如果匹配到,则显示右表对应的数据;匹配不到,也要显示。只不过右表的所有字段使用null进行填充!

**左连接查询语法格式:**
字段
表1说明:
例1:使用左连接查询学生表与班级表,获取每一学生对应的班级信息,要求没有对应的班级也要显示。
+------+--------+--------+----------+ +------+--------+--------+----------+ | 5 | 大乔 | 97.00 | UI | | 2 | 貂蝉 | 99.00 | UI | | 1 | 刘备 | 100.00 | Java | | 4 | 关羽 | 96.00 | Python | | 3 | 赵云 | 98.00 | Python | +------+--------+--------+----------+
**小结**
以右表为主根据条件查询左表数据,如果根据条件查询左表数据不存在则使用null值填充

**右连接查询语法格式:**
字段
表1说明:
例1:使用右连接查询学生表与班级表:
**小结**
外部那个select语句则称为主查询语句。
**作用:**子查询比较适合复杂查询以及多层级查询结构。
**主查询和子查询的关系:**
**了解:子查询的应用场景**
答:在我们需求的基础上,如果这个需求需要通过多条SQL语句分步查询的情况,一般都需要基于子查询。
注:子查询会全表扫描两次,大数据量下需谨慎使用。所以我们说了解就行。
areas.sql
+----------------------+
+----------------------+
+----------------------+
---------------------------------------------------------------------------------------注意事项: