知识点:
基础查询关键字: select:查什么 from: 从哪儿查
基础查询格式: select [distinct] 字段名 | * from 表名;
[]:可以省略
|: 或者
*: 对应表的所有字段名
distinct: 去除重复内容
as : 可以给表或者字段起别名
-- 1.基础查询
格式: select [distinct]字段名 from 表名;
-- 需求1: 查询所有的商品数据
select pid,pname,price,category_id from product;
select * from product;
-- 需求2: 只查询商品价格
select price from product;
-- 需求3: 只查询商品价格,要求去重展示
select DISTINCT price from product;
-- 需求4: 查询商品名称和商品价格,要求给字段起别名
-- 注意: 实际工作不建议用中文,下述仅仅为了演示,as关键字: 给表或者字段起别名
select pname as 商品名称,price as 商品价格 from product;
-- 需求5: 要求所有的商品加10元展示
select pname ,price+10 from product;
--2.条件查询
知识点:
条件查询关键字: where
条件查询基础格式: select 字段名 from 表名 where 条件;
比较运算符: > < >= <= != <>
逻辑运算符: and or not
范围 查询: 连续范围:between x and y 非连续范围: in(x,y)
模糊 查询: 关键字:like %:0个或者多个字符 _:一个字符
非空 判断: 为空: is null 不为空:is not null
条件查询—比较查询
-- 1.比较运算符
-- 需求1: 查询价格大于5000的商品信息
select * from product where price > 5000;
-- 需求2: 查询价格小于2000的商品信息
select * from product where price < 2000;
-- 需求3: 查询商品价格等于400的商品信息
select * from product where price = 440;
-- 需求4: 查询商品价格大于等于2000的商品信息
select * from product where price >= 2000;
-- 需求5: 查询商品价格小于等于5000的商品信息
select * from product where price <= 5000;
-- 需求6: 查询商品价格不等于2000的商品信息
select * from product where price != 2000;
select * from product where price <> 2000;
条件查询—逻辑查询
-- 2.逻辑运算符
-- 需求1: 统计商品价格大于等于2000并且小于等于5000的商品信息
select * from product where price >= 2000 and price <=5000;
-- 需求2: 统计商品价格等于1,或者等于200,或者等于3000的商品信息
select * from product where price = 1 or price = 200 or price = 3000;
-- 需求3: 统计商品价格不在 2000-5000之间 的商品信息
select * from product where price < 2000 or price > 5000;
select * from product where not (price >= 2000 and price <=5000);
条件查询—范围查询
-- 3.范围查询
-- 需求1: 统计商品价格大于等于2000并且小于等于5000的商品信息
-- between x and y : 包含x和y
select * from product where price BETWEEN 2000 and 5000;
-- 需求2: 统计商品价格等于1,或者等于200,或者等于3000的商品信息
select * from product where price in (1,200,3000);
-- 需求3: 统计商品价格不在 2000-5000之间 的商品信息
select * from product where price not BETWEEN 2000 and 5000;
-- 需求4: 统计商品名称是小米或者华为或者花花公子的商品信息
select * from product where pname in ('小米','华为','花花公子');
条件查询—模糊查询
-- 4.模糊查询
-- 需求1: 查找商品名称带'想'字的商品信息
select * from product where pname like '%想%';
-- 需求2: 查找商品名称以'海'字开头的商品信息
select * from product where pname like '海%';
-- 需求3: 查找商品名称以'斯'结尾的商品信息
select * from product where pname like '%斯';
-- 需求4: 查找商品名称以'海'字开头并且是2个字的商品信息
select * from product where pname like '海_';
-- 需求5: 查找商品名称以'海'字开头并且是4个字的商品信息
select * from product where pname like '海___';
-- 需求6: 查找商品名称以'斯'结尾的并且3个字商品信息
select * from product where pname like '__斯';
-- 需求7: 查找商品名称第2个字是'想'字的商品信息
select * from product where pname like '_想%';
条件查询—非空判断
-- 5.非空判断
/*注意: mysql中的null和空字符串''以及字符串'null'不是一回事
mysql中null代表空的,没有任何意义的
''代表空字符串
'null'代表具体字符串
*/
-- 需求1: 查找category_id为空(null)的数据
select * from product where category_id IS NULL;
-- 需求2: 查找category_id不为空(null)的数据
select * from product where category_id IS NOT NULL;
条件查询—排序查询
关键字: order by
排序查询格式: select 字段名 from 表名 ... order by 字段名 asc|desc;
asc: 升序 (默认)
desc: 降序
-- 关键字: order by 字段名
-- 细节: asc默认升序 desc降序
-- 需求1: 根据价格升序排序所有商品
select * from product order by price asc;
select * from product order by price;
-- 需求2: 根据价格降序排序所有商品
select * from product order by price desc;
-- 需求3: 查询所有category_id为c002的商品,并按价格升序排序
select * from product where category_id = 'c002' order by price;
-- 需求4: 查询所有category_id为c002的商品,并按价格降序排序
select * from product where category_id = 'c002' order by price desc;
-- 需求5: 查询所有商品,先按照价格降序排序,如果价格相同,再按照分类id降序排序
select * from product order by price desc , category_id desc;
聚合函数
聚合函数: 又叫统计函数也叫分组函数
常见聚合函数: count() sum() avg() max() min()
注意: 聚合函数(字段名)方式会自动忽略null值
统计数据的时候,即使某条记录为空,依然也算一条数据
如何不忽略null值统计个数?: count(主键)或者count(*)也可以用cont(常量)
-- count():求个数
-- 需求1: 统计商品总个数
select count() from product;
select count(1) from product;
select count(pid) from product;
*-- 需求2: 统计商品分类id不为空的商品个数
select count(*) from product where category_id is not null;
select count(category_id) from product;
-- sum(): 求和
-- 需求3: 统计所有商品的总价
select sum(price) from product;
-- 需求4: 统计所有分类id为'c002'商品的总价
select sum(price) from product where category_id = 'c002';
-- avg():求平均值
-- 需求5: 统计所有商品的平均价格
select avg(price) from product;
-- 需求6: 统计所有分类id为'c002'商品的平均价格
select avg(price) from product where category_id = 'c002';
-- max():求最大值
-- 需求5: 统计所有商品的最大价格
select max(price) from product;
-- 需求6: 统计所有分类id为'c002'商品的最大价格
select max(price) from product where category_id = 'c002';
-- min(): 求最小值
-- 需求7: 统计所有商品的最大价格
select min(price) from product;
-- 需求8: 统计所有分类id为'c002'商品的最大价格
select min(price) from product where category_id = 'c002';
条件查询—分组查询
关键字:group by
分组查询是指使用字句对查询信息进行分组。
分组查询基础格式: select 分组字段名,聚合函数(字段名) from 表名 group by 分组字段名;
分组查询进阶格式: select 分组字段名,聚合函数(字段名) from 表名 [where 非聚合条件] group by 分组字段名 [having 聚合条件];
having与where的区别:
having分组条件,where用于非分组条件
1).having是在分组后对数据进行过滤,where是在分组前对数据进行过滤
2).having后面可以使用分组函数(统计函数),where后面不可以使用分组函数。
where和having的区别?
书写顺序: where在group by 前,having在group by后
执行顺序: where在group by 前,having在group by后
分组函数: where后不能跟聚合条件,只能跟非聚合条件,having后可以使用聚合条件,也可以使用非聚合条件(不建议)
应用场景: 建议大多数过滤数据都采用where,只有当遇到聚合条件的时候再使用having
使用别名: where后不能使用别名,having后可以使用别名
**distinct与group by的区别**
1)distinct只能做去重操作
2)而group by 不仅能够完成去重操作,还能完成其他条件筛选操作
**重点:在聚合查询中,select后的字段名要么在聚合函数内出现,要么在group by后出现**
如果select后出现字段名,但又能运行,是因为这个字段名不参与计算,只是起到一个对应指明的作用,而且它跟分组字段名一致,实际上select后面没有字段名也是能运行的,只不过你不知道聚合后哪个是哪个的
例如:
select category_id,count(*) as cnt from product group by category_id;
select count(*) as cnt from product group by category_id;-- 这里不指明,虽然统计了,但是你不知道哪个对应哪个
/*
查询语句实际上是先使用 `count(*)`函数对 `category_id`字段进行计数,
然后根据 `category_id`进行分组,
最后使用 `having count(*)>1`来过滤出具有重复 `category_id`的记录。
因此,尽管在 `SELECT`语句后面指定了字段名,但实际上这个字段并不直接参与查询结果的计算和返回。
它只是用来在后续的聚合操作中指定要计数的字段。
*/
注意: select后的字段名要么在group by后面出现过,要么写到聚合函数中,否则报错...sql_mode=only_full_group_by
-- 需求1.查找所有分类,要求去重
select distinct category_id from product;
select category_id from product group by category_id;
方式1 原始单独统计
select count(*) from product where category_id is null;#特殊
select category_id,count(*) from product where category_id='c001';#有等号限制才行
方式2 group by 统计
在聚合查询中,select后的字段名要么在聚合函数内出现,要么在group by后出现
select category_id,count() as cnt from product group by category_id;-- 这里select后的字段名是起到一个指明统计后的字段,不起计算作用
*select count(*) as cnt from product group by category_id;-- 这里不指明,虽然统计了,但是你不知道哪个对应哪个
-- 需求3.要求把商品分类id为null的数据过滤,然后统计各个分类商品的个数,最终只展示分类个数大于1的信息
select category_id,count() from product where category_id is not null group by category_id having count()>1;
-- 需求4 要求把商品分类id要求把商品分类id为null的数据过滤,然后统计各个分类商品的个数,最后只展示分类个数大于1的数
-- where后面不能跟分组聚合条件,否则报错
select category_id,count() from product
where category_id is not null
group by category_id
having count()>1;
select category_id,count() from product
where category_id is not null and category_id not in ('','null')
group by category_id
having count()>1;
-- 注意: having后可以跟分组聚合条件,也可以跟非分组聚合条件(不建议,因为会降低效率)
select category_id,count() from product
group by category_id
having category_id is not null and count()>1;
条件查询—分页查询
关键字: limit
分页查询基础格式: select 字段名 from 表名 limit x,y;
x: 起始索引,默认从0开始 x = (页数-1)*y
y: 本次查询的条数
注意: limit能完成topN需求,但是不能考虑到并列情况,此问题可以使用后期学习的开窗函数解决
--需求1.每页展示4条,要求把每页数据都单独筛选出来
-- 第一页
select * from product limit 0,4;
-- 第二页
select * from product limit 4,4;
-- 结论:每页起始索引=(当前页-1)*每页的展示条数,展示条数
-- 需求2.查找商品价格最高的前3条数据
select * from product order by price desc limit 0,3;
-- 注意:如果骑士索引是0,那么可以忽略不写
select * from product order by price desc limit 3;
-- 需求3.查找商品价格最低的三条数据
select * from product order by price asc limit 3;
拓展:快速复制表与其他库使用其他表
其他库使用其他表
-- 如果在day03库中使用day02的表
-- 库名.表名
select * from day02.product;
快速复制表(会有部分约束缺失)
test和test2是复制后的新表名
-- 快速复制表的两种方式
方式一
-- 快速复制表结构
create table test like day02.product;
-- 快速插入数据到表中
insert into product select * from day02.product;
方式二
-- 快速复制表结构和数据
create table test2 as
select * from day02.product;
拓展:sql底层顺序
书写顺序:select [distinct] ->from ->where ->group by ->having -> order by -> limit
运行顺序: from —> where -> group by ->having -> select [distinct] -> order by -> limit
需求:把分类id为null的商品过滤掉,然后筛选分类个数大于1的信息,最后只展示个数最多的分类信息
select category_id,count(*) as cnt
from product
where category_id is not null#where不能起别名
group by category_id
having cnt>1
order by cnt desc
limit 1
;
-- sql语句执行顺序详解
select * from product ; -- 1.从硬盘读出一个伪表
select * from product where category_id is not null; -- 2.where过滤伪表
select category_id from product where category_id is not null group by category_id; -- 3。分组将伪表分成多个小部分,别名这里使用,这里*号是错误的,正确的应该是字段名
select category_id as cid, count(*) as cnt from product where category_id is not null group by category_id having cnt>1; -- 4。having过滤
select category_id as cid, count(*) as cnt from product where category_id is not null group by category_id having cnt>1; -- 5。select这里将别名或者真字段名将伪表拼接
select category_id as cid, count(*) as cnt from product where category_id is not null group by category_id having cnt>1 order by category_id; -- 6。然后排序
select category_id as cid, count(*) as cnt from product where category_id is not null group by category_id having cnt>1 order by category_id limit 3; -- 7。最后进行展示条数
拓展:SQL版本问题
5.x老版本:select后字段不受限制
8.x新版本:select后字段要么在聚合函数内出现,要么在group by后出现