认真学SQL——MySQL入门之DQL单表查询

知识点:

基础查询关键字: 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后出现

你可能感兴趣的:(sql,mysql,数据库)