MySQL数据查询, 单表查询,多表查询知识

本文详细介绍了MySQL中的数据查询,包括单表查询和多表查询的各种方法,如基础查询、条件查询(比较、逻辑、范围、模糊和非空判断)、快速复制表、排序、聚合函数、分组和分页查询。此外,还讲解了外键的概念和使用,以及不同类型的连接查询(交叉、内、左外和右外连接)的应用。

知识点:
MySQL数据查询,单表查询,多表查询的使用


目录

系列文章目录

单表查询

1.准备数据

2.基础查询

知识点:

示例:

3.条件查询

知识点:

比较查询

逻辑查询

范围查询

模糊查询

非空判断

4.快速复制表

知识点:

示例:

5.排序查询

知识点:

示例:

6.聚合函数

知识点:

示例:

7.分组查询

知识点:

示例:

8.分页查询

知识点:

示例:

多表查询

外键

外键约束[了解]

修改存储引擎

演示外键约束

查看依赖图

连接查询

数据准备

交叉连接[慎用]

内连接(常用)

左外连接

右外连接



单表查询

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;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Elysiumk

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值