知识点:
MySQL数据查询,单表查询,多表查询的使用
目录
单表查询
1.准备数据
# 1.数据准备 use day02_db; # 创建商品表 CREATE TABLE product ( pid INT PRIMARY KEY, pname VARCHAR(20), price DOUBLE, category_id VARCHAR(32) ); # 插入数据 INSERT INTO product(pid,pname,price,category_id) VALUES(1,'联想',5000,'c001'); INSERT INTO product(pid,pname,price,category_id) VALUES(2,'海尔',3000,'c001'); INSERT INTO product(pid,pname,price,category_id) VALUES(3,'雷神',5000,'c001'); INSERT INTO product(pid,pname,price,category_id) VALUES(4,'杰克琼斯',800,'c002'); INSERT INTO product(pid,pname,price,category_id) VALUES(5,'真维斯',200,'c002'); INSERT INTO product(pid,pname,price,category_id) VALUES(6,'花花公子',440,'c002'); INSERT INTO product(pid,pname,price,category_id) VALUES(7,'劲霸',2000,'c002'); INSERT INTO product(pid,pname,price,category_id) VALUES(8,'香奈儿',800,'c003'); INSERT INTO product(pid,pname,price,category_id) VALUES(9,'相宜本草',200,'c003'); INSERT INTO product(pid,pname,price,category_id) VALUES(10,'面霸',5,'c003'); INSERT INTO product(pid,pname,price,category_id) VALUES(11,'好想你枣',56,'c004'); INSERT INTO product(pid,pname,price,category_id) VALUES(12,'香飘飘奶茶',1,'c005'); INSERT INTO product(pid,pname,price,category_id) VALUES(13,'海澜之家',1,'c002'); INSERT INTO product(pid,pname,price,category_id) VALUES(14,'小米',1999,''); INSERT INTO product(pid,pname,price,category_id) VALUES(15,'华为',6999,'null'); INSERT INTO product(pid,pname,price,category_id) VALUES(16,'蜜雪冰城',1,null);
2.基础查询
知识点:
基础查询关键字: select:查什么 from: 从哪儿查
基础查询格式: select [distinct] 字段名 | * from 表名;
[]:可以省略
|: 或者
*: 对应表的所有字段名
distinct: 去除重复内容
as : 可以给表或者字段起别名
示例:
# 2.基础查询 # 需求1: 查询所有的商品信息 select pid,pname,price,category_id from product; select * from product; # 需求2: 只查询商品名称和对应价格 select pname,price from product; # 需求3: 查询商品分类id,要求去重 select distinct category_id from product; # 需求4: 查询商品名称和对应价格,要求最终展示字段名为商品名称和商品价格 # 实际工作中不建议用中文,此处仅仅为了演示 select pname as 商品名称,price as 商品价格 from product; # 注意: as 关键字可以省略 select pname 商品名称,price 商品价格 from product; # 需求5: 所有的商品价格要求加100元展示 select pname 商品名称,price+100 商品价格 from product;
3.条件查询
知识点:
条件查询关键字: where
条件查询基础格式: select 字段名 from 表名 where 条件;
比较运算符: > < >= <= != <>
逻辑运算符: and or not
范围 查询: 连续范围:between x and y 非连续范围: in(x,y)
模糊 查询: 关键字:like %:0个或者多个字符 _:一个字符
非空 判断: 为空: is null 不为空:is not null
比较查询
# 1.比较运算符: > < >= <= != <> # 需求1: 查询商品价格大于800的商品信息 select * from product where price > 800; # 需求2: 查询商品价格小于800的商品信息 select * from product where price < 800; # 需求3: 查询商品价格大于等于800的商品信息 select * from product where price >= 800; # 需求4: 查询商品价格小于等于800的商品信息 select * from product where price <= 800; # 需求5: 查询商品价格不等于800的商品信息 select * from product where price != 800; select * from product where price <> 800;
逻辑查询
# 2.逻辑运算符: and or not # 需求1: 查询商品价格介于200-2000之间(含200,2000)的商品信息 select * from product where price >= 200 and price <= 2000; # 需求2: 查询商品价格等于200或者等于2000的商品信息 select * from product where price = 200 or price = 2000; # 需求3:查询商品价格不在200-2000之间(含200,2000)的商品信息 select * from product where not (price >= 200 and price <= 2000);
范围查询
# 3.范围查询: 连续范围:between x and y 非连续范围: in(x,y) # 需求1: 查询商品价格介于200-2000之间(含200,2000)的商品信息 select * from product where price between 200 and 2000; # 需求2: 查询商品价格等于200或者等于2000的商品信息 select * from product where price in(200,2000); # 需求3: 查询商品价格不在200-2000之间(含200,2000)的商品信息 select * from product where price not between 200 and 2000; # 需求4: 查询商品价格不等于200和2000的其他商品信息 select * from product where price not in(200,2000);
模糊查询
# 4.模糊 查询: 关键字:like %:0个或者多个字符 _:一个字符 # 需求1: 查询商品名称以'香'开头的所有商品信息 select * from product where pname like '香%'; # 需求2: 查询商品名称包含'想'字的所有商品信息 select * from product where pname like '%想%'; # 需求3: 查询商品名称以'斯'字结尾的所有商品信息 select * from product where pname like '%斯'; # 需求4: 查询商品名称第三个字是'斯'的商品信息 select * from product where pname like '__斯%'; # 需求5: 查询商品名称以'香'开头并且是三个字的所有商品信息 select * from product where pname like '香__';
非空判断
# 5.非空 判断: 为空: is null 不为空:is not null # sql中null代表空的无意义的意思,和空字符串''以及字符串'null'不是一回事!!! # 需求1: 查询商品分类id为空的商品信息 select * from product where category_id is null; # 需求2: 查询商品分类id不为空的商品信息 select * from product where category_id is not null; # 需求3: 查询商品分类id是空字符串的商品信息 select * from product where category_id = ''; # 需求4: 查询商品分类id是名为'null'的商品信息 select * from product where category_id = 'null';
4.快速复制表
知识点:
快速查看建表语句: ctrl+Q 快速复制表结构(含约束): create table 新表名 like 就表名; 查询结果快速插入到表中: insert into 表名 select语句; 快速复制表结构和数据(丢失约束): create table 新表名 [as] select语句;
示例:
# 创建数据库 create database day03_db; # 使用数据库 use day03_db; # 创建表 # 需求: 要创建的表和day02_db下的product一模一样 # 方式1: 原生方式>> 找到之间的笔记直接复制之前的建表语句和插入数据语句,然后执行 # 方式2: 快捷键方式>> show create table 表名 或者选中对应的表,按ctrl+q查看建表语句 # 方式3: 先快速复制表结构生成新表,然后把查询数据快速插入到新表中 # 先创建新表快速复制原表结构 create table day03_db.product like day02_db.product; # 再从原表中查询数据快速插入到新表中 insert into day03_db.product select * from day02_db.product; # 方式4: 建表和插数据一步到位 # 弊端: 约束会损失 create table day03_db.product2 as select * from day02_db.product; # 注意: as可以省略 create table day03_db.product3 select * from day02_db.product;
5.排序查询
知识点:
排序查询关键字: order by
排序查询基础格式: select 字段名 from 表名 order by 排序字段名 asc|desc;
asc : 升序(默认)
desc: 降序
排序查询进阶格式: select 字段名 from 表名 order by 排序字段1名 asc|desc , 排序字段2名 asc|desc;
注意: 如果order by后跟多个排序字段,先按照前面的字段排序,如果有相同值的情况再按照后面的排序规则排序
示例:
# 排序查询 # 需求1: 查询所有商品信息,按照价格升序排序 select * from product order by price asc; -- 报黄警告,此处asc多余 select * from product order by price ; -- 默认升序 # 需求2: 查询所有商品信息,按照价格降序排序 select * from product order by price desc; # 需求3: 查询所有商品信息,先按照价格降序排序,价格相同再按照分类id升序排序 select * from product order by price desc,category_id; # 需求4: 查询所有商品信息,先按照价格降序排序,价格相同再按照分类id降序排序 select * from product order by price desc,category_id desc; # 需求5: 查询c002分类的所有商品,并且按照价格降序排序 select * from product where category_id='c002' order by price desc;
6.聚合函数
知识点:
聚合函数: 又叫统计函数,也叫分组函数 常用聚合函数: sum() count() avg() max() min() 聚合查询基础格式: select 聚合函数(字段名) from 表名; 注意: 此处没有分组默认整个表就是一个大的分组 注意: 聚合函数(字段名)会自动忽略null值,以后统计个数一般用count(*)统计因为它不会忽略null值
示例:
# 注意: 别名不建议用中文,以下仅仅为了演示 # 需求1.1: 统计所有商品的个数 select count(*) as 商品个数 from product; select count(pid) as 商品个数 from product; # 需求1.2: 统计商品分类不为空的一共有多少条记录 select count(*) from product where category_id is not null; select count(category_id) from product; # 需求2: 统计所有商品的总价格 select sum(price) as 商品总价 from product; # 需求3: 统计所有商品中的最大价格 select max(price) as 最大价格 from product; # 需求4: 统计所有商品中的最小价格 select min(price) as 最小价格 from product; # 需求5: 统计所有商品的平均价格 select avg(price) as 平均价格 from product; # 需求6: 查询c002分类的所有商品中最大价格 select max(price) as 最大价格 from product where category_id = 'c002'; # 需求7: 查询商品价格大于2000的有几个 select count(*) from product where price > 2000; # 需求8: 查询c001分类的的商品个数 select count(*) from product where category_id = 'c001';
7.分组查询
知识点:
分组查询关键字: group by 分组查询基础格式: select 分组字段名,聚合函数(字段名) from 表名 group by 分组字段名; 注意: select后的字段名要么在group by后面出现过,要么写到聚合函数中,否则报错...sql_mode=only_full_group_by 分组查询进阶格式: select 分组字段名,聚合函数(字段名) from 表名 [where 非聚合条件] group by 分组字段名 [having 聚合条件]; where和having的区别? 书写顺序: where在group by 前,having在group by后 执行顺序: where在group by 前,having在group by后 分组函数: where后不能跟聚合条件,只能跟非聚合条件,having后可以使用聚合条件,也可以使用非聚合条件(不建议) 应用场景: 建议大多数过滤数据都采用where,只有当遇到聚合条件的时候再使用having 使用别名: where后不能使用别名,having后可以使用别名
示例:
# 需求1: 统计各个分类的商品个数 select category_id, count(*) from product group by category_id; # 需求2: 统计各个分类的商品个数,筛选个数大于1的分类信息 select category_id, count(*) from product group by category_id having count(*) > 1; # 需求3: 先过滤分类id是null的商品,然后统计各个分类的商品个数 select category_id, count(*) from product where category_id is not null group by category_id; /* # having后不建议跟非聚合条件(效率低),所有非聚合条件建议放到where后 select category_id, count(*) as cnt from product group by category_id having category_id is not null; */ # 需求4: 先过滤分类id是null的商品,然后统计各个分类的商品个数,最后筛选个数大于1的分类信息 select category_id, count(*) as cnt from product where category_id is not null group by category_id having cnt > 1; /* # having后不建议跟非聚合条件(效率低),所有非聚合条件建议放到where后 select category_id, count(*) as cnt from product group by category_id having category_id is not null and cnt > 1; */
8.分页查询
知识点:
分页查询关键字: limit
分页查询基础格式: select 字段名 from 表名 limit x,y;
x: 起始索引,默认从0开始 x = (页数-1)*y
y: 本次查询的条数
注意: limit能完成topN需求,但是不能考虑到并列情况,此问题可以使用后期学习的开窗函数解决
示例:
/* 需求1:一共16条数据,每页展示4条,依次求出每页数据 分析: limit x,4 计算x: x= (页数-1)*4 */ # 第1页 select * from product limit 0,4; # 第2页 select * from product limit 4,4; # 第3页 select * from product limit 8,4; # 第4页 select * from product limit 12,4; # 需求2: 查询最大价格的商品信息 # 分析: 先按照价格降序排序,只第一条 select * from product order by price desc limit 0,1; # 注意: 如果起始索引是0,那么可以省略 select * from product order by price desc limit 1; # 需求3: 查询最小价格的3个商品信息 select * from product order by price limit 3;
多表查询
==本质: 把多个表通过主外键关联关系连接(join)合并成一个大表,再去查询==
外键
外键概念: 在从表(多方)创建一个字段,引用主表(一方)的主键,对应的这个字段就是外键。
外键特点:
1:从表外键的值是对主表主键的引用。
2:从表外键类型,必须与主表主键类型一致。
外键约束[了解]
修改存储引擎
# 外键约束
# 分类表
CREATE TABLE category
(
cid VARCHAR(32) PRIMARY KEY,
cname VARCHAR(100) #分类名称
);
# 商品表
CREATE TABLE products
(
pid varchar(32) PRIMARY KEY,
pname VARCHAR(40),
price DOUBLE,
category_id varchar(32)
);
# 演示没有外键约束出现的问题
# 演示往从表中插入主表不存在的数据
insert into products values('p001','联想笔记本',4999,'c001'); # 插入成功,因为没有约束
insert into products values('p002','华为笔记本',4999,'c001'); # 插入成功,因为没有约束
insert into products values('p003','小米笔记本',4999,'c001'); # 插入成功,因为没有约束
# 往主表中插入数据
insert into category values('c001','电脑');
# 演示主表删除从表已经引用的数据
delete from category where cid = 'c001'; # 删除成功,因为没有约束
# 问题1:以上问题如何解决? 添加外键约束
# 问题2:如何添加外键约束? 前提是innodb存储引擎,myisam存储引擎不支持外键约束
# 注意: 如果修改了存储引擎,需要重新建表才能生效,否则还是原来的存储引擎
# 查看之前建表语句
show create table category; -- ENGINE=MyISAM ...
show create table products; -- ENGINE=MyISAM ...
演示外键约束
外键约束关键字: foreign key
外键约束作用:
限制从表插入: 如果从表插入的外键值,在主表中不存在,就插入失败
限制主表删除: 如果主表的主键值已经被从表引用,在主表删除该数据的时候,就删除失败
# 删除表
drop table category;
drop table products;
# 分类表
CREATE TABLE category
(
cid VARCHAR(32) PRIMARY KEY,
cname VARCHAR(100) #分类名称
);
# 商品表
CREATE TABLE products
(
pid varchar(32) PRIMARY KEY,
pname VARCHAR(40),
price DOUBLE,
category_id varchar(32)
);
# 再次建表语句
show create table category; -- ENGINE=InnoDB ...
show create table products; -- ENGINE=InnoDB ...
# 方式1:建表后,在从表中添加外键约束
alter table products add foreign key(category_id) references category(cid);
# 方式2:建表同时添加(建议)
CREATE TABLE products2
(
pid varchar(32) PRIMARY KEY,
pname VARCHAR(40),
price DOUBLE,
category_id varchar(32),
foreign key(category_id) references category(cid)
);
# 演示外键约束的限制作用:
# 演示往从表中插入主表不存在的数据
insert into products values('p001','联想笔记本',4999,'c001'); # 插入失败,因为有约束,限制从表插入数据
# 往主表中插入数据
insert into category values('c001','电脑');
insert into products values('p001','联想笔记本',4999,'c001'); # 插入成功,因为主表已经有了c001记录
insert into products values('p002','小米笔记本',4999,'c001'); # 插入成功,因为主表已经有了c001记录
# 演示主表删除从表已经引用的数据
delete from category where cid = 'c001'; # 删除失败,因为有约束,限制主表删除数据
查看依赖图
连接查询
数据准备
# 多表查询数据准备 # 创建hero表 CREATE TABLE hero ( hid INT PRIMARY KEY, hname VARCHAR(255), kongfu_id INT ); # 创建kongfu表 CREATE TABLE kongfu ( kid INT PRIMARY KEY, kname VARCHAR(255) ); # 插入hero数据 INSERT INTO hero VALUES(1, '鸠摩智', 9),(3, '乔峰', 1),(4, '虚竹', 4),(5, '段誉', 12); # 插入kongfu数据 INSERT INTO kongfu VALUES(1, '降龙十八掌'),(2, '乾坤大挪移'),(3, '猴子偷桃'),(4, '天山折梅手');
交叉连接[慎用]
交叉连接关键字: cross join 显式交叉连接格式: select * from 左表 cross join 右表; 隐式交叉连接格式: select * from 左表,右表; 注意: 交叉连接了解即可,因为它本质就是一个错误,又叫笛卡尔积(两个表记录数的乘积) 注意: 左表和右表没有特殊含义,只是在前面是左表,在后面的是右表
# 示例: # 1.交叉连接(慎用) # 显式 select * from hero cross join kongfu; # 隐式 select * from hero , kongfu;
内连接(常用)
内连接关键字: inner join ... on 显式内连接格式: select * from 左表 inner join 右表 on 关联条件; 隐式内连接格式: select * from 左表 , 右表 where 关联条件; 注意: 左表和右表没有特殊含义,只是在前面是左表,在后面的是右表
# 示例: # 2.内连接(常用) # 隐式 select * from hero , kongfu where hero.kongfu_id=kongfu.kid; # 显式 select * from hero inner join kongfu on hero.kongfu_id=kongfu.kid;
左外连接
内连接关键字: left outer join ... on 左外连接格式: select * from 左表 left outer join 右表 on 关联条件; 注意: 左表和右表没有特殊含义,只是在前面是左表,在后面的是右表
# 示例: # 3.左外连接 # 需求2: 获取所有的英雄名称和对应的功夫,没有功夫的null补全 # 左表所有数据展示,右表只展示和左表关联上的数据,其他用null补全 select hname,kname from hero left outer join kongfu on hero.kongfu_id=kongfu.kid;
右外连接
内连接关键字: right outer join ... on 左外连接格式: select * from 左表 right outer join 右表 on 关联条件; 注意: 左表和右表没有特殊含义,只是在前面是左表,在后面的是右表
# 示例: # 4.右外连接 # 需求3: 获取所有的功夫和对应的英雄,没有英雄的null补全 # 左表所有数据展示,右表只展示和左表关联上的数据,其他用null补全 select kname,hname from hero right outer join kongfu on hero.kongfu_id=kongfu.kid;
本文详细介绍了MySQL中的数据查询,包括单表查询和多表查询的各种方法,如基础查询、条件查询(比较、逻辑、范围、模糊和非空判断)、快速复制表、排序、聚合函数、分组和分页查询。此外,还讲解了外键的概念和使用,以及不同类型的连接查询(交叉、内、左外和右外连接)的应用。

479

被折叠的 条评论
为什么被折叠?



