MySQL第三讲

目录

三、模糊查询与分组查询

1、模糊检索

1.1 like

1.2 正则

1.3 between and

1.4 in

2、分组查询

2.1聚合函数

2.2 分组函数

2.3 having函数

3、关联查询

3.1 关联查询的作用

3.2 关联查询的分类

4、自连接

三、模糊查询与分组查询

1、模糊检索

1.1 like

模糊查询的结果不是一定的,只是大概相似的结果,对应的,用户输入的查询条件也可以是模糊的、大概的、不明确的。

运算符说明
%代表任意长度的字符串
_代表一个字符
escape规定转义字符
\转义字符

符号解释案例:

-- 查询user表中名字带有“_”字符的用户
-- 这两种写法效果是一样的
select * from user where name like concat("%","\_","%");
select * from user where name like concat("%","$_","%") escape "$";
-- 因为_是特殊字符,所以查找时,应该将_看做是普通字符,需要用转义字符来标识;
-- escape "$" 的意思就是,把$看做是转义字符,$后面的字符就是普通字符,没有特殊含义
create table t_class(
id int primary key auto_increment,
cname varchar(100)
);
​
-- 创建学生表 
create table tab_student(
id int primary key auto_increment,
stuname varchar(100),
sex varchar(2),
begintime date,
gradutetime date,
idcard varchar(18),
age int,
address varchar(200),
cid int,
CONSTRAINT fk_classid FOREIGN key(cid)
references t_class(id)
);
insert into tab_student(id,stuname,sex,begintime,gradutetime,idcard,age,address) values('2','雷wl',"男",'2022-1-1','2022-12-30','412723xxxxxxxx0813','35','周口市');
insert into tab_student(id,stuname,sex,begintime,gradutetime,idcard,age,address) values(null,'雷wl1',"女",'2022-1-1','2022-12-30','412723xxxxxxxx0813','15','郑州市');
insert into tab_student(id,stuname,sex,begintime,gradutetime,idcard,age,address) values(null,'雷wl22',"女",'2022-1-1','2022-12-30','412723xxxxxxxx0813','30','上海市');
insert into tab_student(id,stuname,sex,begintime,gradutetime,idcard,age,address) values(null,'a雷wl5',"男",'2022-1-1','2022-12-30','412723xxxxxxxx0813','60','北京市');
​
select * from tab_student;
-- 模糊查询 关键字:like / between and / in  
-- like :模糊查询提取的数据不一定是确切的
-- —代表1个字符 两个_就代表有两个字符
select * from tab_student where stuname like '雷__';-- 查询所有的雷xx
select * from tab_student where stuname like '雷___';-- 查询所有的雷xxx
select * from tab_student where stuname like concat('雷','__');-- 查询所有的雷xxx
-- like %代表任意个字符
select * from tab_student where stuname like '雷%';
select * from tab_student where stuname like concat('雷','%');
-- 不论'雷'在字符串的哪个位置都能查询出来
select * from tab_student where stuname like '%雷%';
select * from tab_student where stuname like concat('%','雷','%');

1.2 正则

MySQL 中的正则表达式与 Java 语言、PHP 语言等编程语言中的正则表达式基本一致。

选项说明例子匹配值示例
^匹配文本的开始字符‘^b’ 匹配以字母 b 开头的字符串book、big、banana、bike
$匹配文本的结束字符‘st$’ 匹配以 st 结尾的字符串test、resist、persist
.匹配任何单个字符‘b.t’ 匹配任何 b 和 t 之间有一个字符bit、bat、but、bite
*匹配零个或多个在它前面的字符‘f*n’ 匹配字符 n 前面有任意个字符 ffn、fan、faan、abcn
+匹配前面的字符 1 次或多次‘ba+’ 匹配以 b 开头,后面至少紧跟一个 aba、bay、bare、battle
<字符串>匹配包含指定字符的文本‘fa’ 匹配包含‘fa’的文本fan、afa、faad
[字符集合]匹配字符集合中的任何一个字符‘[xz]‘ 匹配 x 或者 zdizzy、zebra、x-ray、extra
[^]匹配不在括号中的任何字符[^abc] 匹配任何不包含 a、b 或 c 的字符串desk、fox、f8ke
字符串{n,}匹配前面的字符串至少 n 次‘b{2}’ 匹配 2 个或更多的 bbbb、bbbb、bbbbbbb
字符串 {n,m}匹配前面的字符串至少 n 次, 至多 m 次‘b{2,4}’ 匹配最少 2 个,最多 4 个 bbbb、bbbb
-- 正则:一套复杂的规则:410或者412打头的身份证
select * from studentinfo where studentno like '410%' or studentno like '412%' 
select * from studentinfo where studentno REGEXP '^41[0|2]'

1.3 between and

-- between and :根据某个字段值的区间范围来查询符合条件的记录,这个范围内有多少数据并不明确
-- between and 的执行效率较高,相对于比较表达式效率高
select * from tab_student where id>3 && id<6;  -- 结果是 id= 4/5
select * from tab_student where id between 4 and 5;-- 结果是 id= 4/5

1.4 in

-- in :用来匹配某个字段的值是几个可数的选项值之一 
-- in 的执行效率比or高
-- 查询地址为 周口市 上海市 北京市的学生
select * from tab_student where address='周口市' or address='上海市' or address='北京市';
select * from tab_student where address in('周口市','上海市','北京市');
-- 查询地址不为 周口市 上海市 北京市的学生
select * from tab_student where address!='周口市' and address!='上海市' and address!='北京市';
select * from tab_student where address not in('周口市','上海市','北京市');

2、分组查询

分组查询显示的结果是根据分组查询的结果,分组之后的表与原始表格的列名就不一致了,所以最后不会显示原本表格中的信息

2.1聚合函数

获取某些列的最大值、最小值、平均值等统计分析信息,有时候还需要计算出究竟查询到多少行数据项。分别有:sum、max、min、avg、count(注意非空值)——计数,结果集有几行

-- 聚合函数 count / sum / avg / max / min /
-- 如果没有group by 所有数据算是一组进行聚合
-- count 关键字:count计数:求所有非空(空指的是count中书写的列的内容全部为空)条数的
-- 语法:select count(列名) from 表名
select * from tab_student;-- 这里使用* 效率会降低
select count(*) from tab_student; -- 这里用*,效率会变高
-- 查询学生表中所有名字为空的学生
select count(*) from tab_student where stuname is null;
-- 查询学生表中所有名字不为空的学生
select count(*) from tab_student where stuname is not null;
-- sum 求总数
select sum(age) from tab_student;
-- max 求最大值
select max(age) from tab_student;
-- min 求最小值
select min(age) from tab_student;
-- avg 求平均值
select avg(age) from tab_student;

2.2 分组函数

-- 分组函数
-- 分组函数一般与聚合函数配合使用
-- 分组后在聚合是每一组的聚合:查询结果处展示的分组列和聚合列,分组列整体不重复
-- 如果查询位置出现普通列:常规会报错,mysql会默认显示第一行
-- group by::一组中只有一条数据来标识每个性别里面有多少学生
select sex,count(*) from tab_student group by sex;
-- 每个班级里面有多少个学生
select count(*) from tab_student group by cid;
-- 每个班级里面每种性别有多少个学生
select cid,sex,count(*) from tab_student group by cid,sex;
-- 每个城市有多少个学生
select address,count(*) from tab_student group by address;

2.3 having函数

-- having:对分组后的数据做过滤
-- 查找班级人数大于2的班级
-- 思路1:
-- 1.先对每个班级的人数分组
-- 2.使用having关键字过滤 人数>2 
select cid,count(*) from tab_student group by cid having count(*)>2;
-- 思路2:
-- 虚表==虚拟表 == 不存在的表
select * from(
select cid,count(*) as a from tab_student group by cid) vir where a>2;

3、关联查询

3.1 关联查询的作用

假如所有数据都存在一张表中,有以下缺点:

1)冗余存储,有些字段只有很少的对象会有,但是必须要设立该字段

2)删除、修改操作风险大

3)过长的数据看起来麻烦,而且占内存比较大

所以存储信息的时候会分在多个表中,这就解决了以上麻烦,但是分表的话,查询起来就比较费时费力,解决这个麻烦就需要用关联查询

3.2 关联查询的分类

关联查询:就是根据一定的条件把多张表数据组合在一起,得到类似于一张表的效果

3.2.1内连接

内连接:也叫等值连接, 内连接和外连接一样都是最常用的连接查询,它根据表中共同的的列进行匹配,特别是两个表存在主外键关系时,通常会使用到内连接查询

返回的结果集是两个表中所有相匹配的数据,舍弃不匹配的数据

两张表都符合关联条件—根据关联条件查询,左右表都有该数据那么该数据显示,如果一张表有一张表没有该数据就不显示。

例如:班级和学生关联查询——班级id=班级id

学生中的班级id在班级中找不到——这个学生不显示

学生班级id直接null——肯定找不到数据所以不显示。

-- 内连接:也叫等值连接
-- 第一种写法格式
-- select 列名from 表1inner join 表2 on 表1和表2 的关联条件inner join 表3 on 表1和表3的 表2 和表3条件--关联条件
-- 第二种写法格式
-- select 列名from  表1  , 表2 , 表3.....where 关联条件和过滤条件
--一般情况下手:关联条件在前 过滤条件在后
-- 过滤条件一般是右往左,右边的过滤先执行。
​
-- 获取所有的学生的信息,并且获取对应的班级id
-- 第一种写法 inner join :inner可以省略不写
select * from tab_student stu inner join t_class cls on stu.cid=cls.id;-- inner 可以省略
select stu.*,cls.* from tab_student stu inner join t_class cls on stu.cid=cls.id;
-- 第二种写法:where的写法
select stu.*,cls.* from tab_student stu,t_class cls where stu.cid=cls.id;

3.2.2 外连接

外连接是至少返回一个表中的所有记录,根据匹配条件有选择性地返回另一张表的记录,如果匹配就显示两表如果不匹配就显示为null

外连接就是在满足表连接关系的情况下不但可以查找出匹配的数据,而且还可以包含左表,右表或是两表中的所有的数据行

-- outer可以省略不写
左外:保证左表数据完整
select 列名
from 左表
left 【outer】 join 右表 on 条件
......
​
右外:保证右表数据完整
select 列名
from 左表
right 【outer】 join 右表 on 条件
......
​
全外连接:保证两表数据完整——Mysql不支持
select 列名
from 左表
full【outer】 join 右表 on 条件
......
-- 外连接:左外连接/右外连接
-- 所有班级里的所有学生
-- 左连接:left outer join 
-- 特点:左表(主表)中的数据全部显示,如果右表中没有数据用null来填充
select * from t_class cls left join tab_student stu on cls.id=stu.cid;
select * from tab_student stu left join t_class cls on cls.id=stu.cid;
​
-- 右连接:right outer join 
select * from tab_student stu right join t_class cls on cls.id=stu.cid;
​
-- 全连接 : union/union all
-- 全连接就是连接左右连接,全连接时,要保持列名一致
-- union :自动去除重复的数据
select cls.*,stu.* from tab_student stu left join t_class cls on cls.id=stu.cid
union
select cls.*,stu.* from tab_student stu right join t_class cls on cls.id=stu.cid;
-- union all :不能去除重复的数据
select cls.*,stu.* from tab_student stu left join t_class cls on cls.id=stu.cid
union all
select cls.*,stu.* from tab_student stu right join t_class cls on cls.id=stu.cid;

3.2.3 交叉连接(笛卡尔乘积)

交叉联接返回左表中的所有行,左表中的每一行与右表中的所有行再一一组合,相当于两个表“相乘”

create table emp(   
empid int primary key auto_increment,   
empname varchar(200));
​
create table dbdate(    
dateid int primary key auto_increment,  
dateinfo date);
​
create table ribao( 
ribaoid int primary key auto_increment, 
empid int , 
dateid int);
​
insert into emp values(null,'zs'),(null,'ls'),(null,'ww')
insert into dbdate values(null,'2021-6-1'),(null,'2021-6-2'),(null,'2021-6-3')
insert into ribao values(null,1,1),(null,2,2),(null,3,3)
-- 交叉连接:笛卡尔乘积
select * from emp a join dbdate b on 1=1
​
select a.empname,b.dateinfo,c.* from emp a cross join 
dbdate b left join ribao c on a.empid=c.empid and b.dateid=c.dateid
​
-- 运行结果
zs  2021-06-01  1   1   1
ls  2021-06-02  2   2   2
ww  2021-06-03  3   3   3
ls  2021-06-01          
ww  2021-06-01          
zs  2021-06-02          
ww  2021-06-02          
zs  2021-06-03          
ls  2021-06-03

4、自连接

create table tab_stu(
    stuid int not null auto_increment primary key ,
    stuname varchar(255) default null,
    zuzhangid int  
);
INSERT INTO `tab_stu` VALUES (1, '于昊辰', NULL);
INSERT INTO `tab_stu` VALUES (2, '郝金林', 1);
INSERT INTO `tab_stu` VALUES (3, '叶帅', NULL);
INSERT INTO `tab_stu` VALUES (4, '张统', 3);
​
select * from tab_stu;
-- 自连接
select * from tab_stu as zuzhang 
join tab_stu as zuyuan 
on zuyuan.zuzhangid=zuzhang.stuid

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值