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)

命令作用:

执行结果:

关键参数:

注意事项:

+-----+-----------------+-------+-------------+ +-----+-----------------+-------+-------------+ | 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开始




分页查询

![](/assets/feishu-images/55f8e678de36413b88e3923b.png)

在SQL语句中,数据表与数据表之间,如果存在关系,一般一共有3种情况:

比如有A、B两张表,A表中的每一条数据,在B表中有一条唯一的数据与之对应。

user_id(用户编号)账号username密码password
001adminadmin888
002itheima123456
user_id(用户编号)真实姓名年龄联系方式
001张三1610086
002李四1810010

我们把用户表与用户详情表之间的关系就称之为一对一关系。

image

比如有A、B两张表,A表中的每一条数据,在B表中都有多条数据与之对应,我们把这种关系就称之为一对多关系

产品分类表

分类id编号分类名称
1手机
2电脑

产品信息表

产品id编号产品名称产品价格所属分类id编号
1Apple iPhone 136799.001
2Redmi Note 93499.001

我们把产品分类表与产品表之间的(分类id的对应)关系就称之为一对多关系。

image

用户表

用户编号登录账号登录密码
1adminadmin888
2itheima123456

权限表

权限id编号权限名称
1增加
2删除
3修改
4查询
image

连接查询可以实现多个表的查询,当查询的字段数据来自不同的表就可以使用连接查询来完成。

连接查询可以分为:

准备数据集:

);

(4,'Shell');

);

( );

(2,'bbbbbb');


笛卡尔积连接,没有意义,但是它是所有连接的基础。其功能就是将表1和表2中的每一条数据进行连接。

结果:




查询两个表中符合条件的共有记录

![](/assets/feishu-images/e94ec9f80ff5223891af3ab3.png)

说明:

例1:使用内连接查询学生表与班级表,查询每个学生对应的具体班级信息。


**小结**




以左表为主根据条件查询右表数据,如果根据条件查询右表数据不存在,使用null值填充

商品分类表

| 编号 | 分类名称 |
|---|---|
| 1 | 手机 |
| 2 | 电脑 |

商品表

| 编号 | 商品名称 | 商品分类编号 |
|---|---|---|
| 1 | Vivo手机 | 1 |
| 2 | Xiaomi手机 | 1 |


| 编号 | 分类名称 | 编号 | 商品名称 | 商品分类编号 |
|---|---|---|---|---|
| 1 | 手机 | 1 | Vivo手机 | 1 |
| 1 | 手机 | 2 | Xiaomi手机 | 1 |
| 2 | 电脑 | null | null | null |

左外连接默认会保留左表,然后与右边的表进行匹配;如果匹配到,则显示右表对应的数据;匹配不到,也要显示。只不过右表的所有字段使用null进行填充!

![](/assets/feishu-images/6b0ff182cd6c4a3f1274c51a.png)

**左连接查询语法格式:**

    字段
    表1

说明:

例1:使用左连接查询学生表与班级表,获取每一学生对应的班级信息,要求没有对应的班级也要显示。

+------+--------+--------+----------+ +------+--------+--------+----------+ | 5 | 大乔 | 97.00 | UI | | 2 | 貂蝉 | 99.00 | UI | | 1 | 刘备 | 100.00 | Java | | 4 | 关羽 | 96.00 | Python | | 3 | 赵云 | 98.00 | Python | +------+--------+--------+----------+


**小结**



以右表为主根据条件查询左表数据,如果根据条件查询左表数据不存在则使用null值填充

![](/assets/feishu-images/a68a7b8a4ba3363270e01bb0.png)

**右连接查询语法格式:**

    字段
    表1

说明:

例1:使用右连接查询学生表与班级表:


**小结**






外部那个select语句则称为主查询语句。


**作用:**子查询比较适合复杂查询以及多层级查询结构。

**主查询和子查询的关系:**


**了解:子查询的应用场景**

答:在我们需求的基础上,如果这个需求需要通过多条SQL语句分步查询的情况,一般都需要基于子查询。

注:子查询会全表扫描两次,大数据量下需谨慎使用。所以我们说了解就行。

areas.sql


+----------------------+
+----------------------+
+----------------------+


---------------------------------------------------------------------------------------

注意事项: