MySQL基础(三):SQL查询语句中的关键字讲解、多表连接操作
下面是小凰凰的简介,看下吧!????人生态度:珍惜时间,渴望学习,热爱音乐,把握命运,享受生活????学习技能:网络 -> 云计算运维 -> python全栈( 当前正在学习中)????您的点赞、收藏、关注是对博主创作的最大鼓励,在此谢过!有相关技能问题可以写在下方评论区,我们一起学习,一起进步。后期会不断更新python全栈学习笔记,秉着质量博文为原则,写好每一篇博文。文章目录1、几
下面是小凰凰的简介,看下吧!
💗人生态度:珍惜时间,渴望学习,热爱音乐,把握命运,享受生活
💗学习技能:网络 -> 云计算运维 -> python全栈( 当前正在学习中)
💗您的点赞、收藏、关注是对博主创作的最大鼓励,在此谢过!
有相关技能问题可以写在下方评论区,我们一起学习,一起进步。
后期会不断更新python全栈学习笔记,秉着质量博文为原则,写好每一篇博文。
文章目录
1、几个重要关键字的执行顺序
# 书写顺序
select id,name from emp where id > 3;
# 执行顺序
from -> where -> select
温馨提示:当一个查询的一个表的字段非常大时,可以使用\G分行展示!
select * from emp\G;
2、where过滤
# 作用:是对整体数据的筛选
select id,name from emp where id between 3 and 6; # 3 =< id <= 6。拓展:not between
select * from emp where salary in (20000,15000,10000); # 薪水在三者之中。拓展:not in
# 模糊查询(%代表匹配任意多个字符,_匹配任意单个字符)
select name,salary from emp where name like '%o%';
# 查询员工姓名是由四个字符组成的姓名和薪资
select name,salary from emp where name like '____'; # 也可以使用char_length(name)=4
# 查询岗位描述为空的员工姓名和岗位名 针对null不用等号 用is
select * from emp where salary is null; # 拓展:is not null
3、group by分组、as别名
(1)group by分组、聚合函数
# 分组实际应用场景
男女比例
部门平均工资
国家之间数据统计
...
'注意:'分组之后,最小可操作单位是组。不能直接获取组内的单条数据,后续有方法可以实现。
# 什么时候需要分组?
遇到关键字:每个、平均、最高、最低
# 实战:
1. 获取每个部门的最高薪资
select post,max(salary) from emp group by post;
select post as '部门',max(salary) as '最高薪资' from emp group by post; # as起别名
==========其他用法===========
最低:min()
平均:avg()
总和:sum()
注:和max使用一样
2. 统计每个部门的人数
select count(id) from emp group by post;
'注意:count的所传的字段必须是not null'
除此之外,可以使用任一字段作为count的计数依据,一般我们选择比较代表性的,比如部门的人数,就可以用独一无二的工号来计数。
(2)as别名
as给字段起别名
select name as '姓名',salary*12 as '年薪' from emp;
as给表起别名
select t1.id,t1.name from emp as t1; # 因为先执行from,因此emp表就变成了t1表,因此select需要是t1,主要是解决表名过长的问题输入麻烦,
(3)分组注意事项
1. 关键字where和group by同时出现时,group by必须在where后面。
2. where先对整体数据进行过滤,之后再进行分组,聚合函数只能在分组之后使用,不能在where中使用!
3. select max(salary) from emp;上面说只能在分组之后使用,那么这个句子是错误的吧!不,它是正确的。'因为默认整体就是一组!'
# 统计各部门年龄在30岁以上的员工的平均薪资
select post,avg(salary) from emp where age > 30 group by post;
4、group_concat与concat
(1)group_concat
我们前面说了分组后无法直接查询某个数据,操作都是以组为单位
!因此我们需要通过group_concat间接查询!
# 查询每个部门下有哪些人
select dpm_id,group_concat(stuff_name) from stuff group by dpm_id;
上面还只是一个简单应用,牛逼操作如下:
它支持拼接操作:
select dpm_id as '部门号',group_concat(stuff_name,':',stuff_age) as '员工信息' from stuff group by dpm_id;
(2)concat
select concat(stuff_name,'_DSB') from stuff where stuff_id != 1;
(3)concat与group_concat的区别
有分组时用group_concat,没有分组用concat
5、having分组之后筛选
having的语法跟where是一样的,且它们都是用来过滤的。
只不过having是用于分组之后的过滤
,因为在分组之后,所以支持聚合函数!
# 统计各部门年龄在30岁以上的员工工资并且保留平均薪资大于一万的部门
select post,avg(salary) from emp
where age > 30
group by post
having avg(salary) > 10000
;
6、distinct去重
一定要注意,必须是完全一样的数据,才能去重。
{'id':1,'name':'hehe','age'=18}
{'id':2,'name':'hehe','age'=18}
{'id':3,'name':'haha','age'=20}
# 从上面我们可以看出第一个和第二个重复了吗?没有重复!
因为1,2的id不同,但是在生产环境中,一般这个id是设置为自增的,'很有可能忽视id',只对比了name、age,这样看就是相同的,最后发现这两个数据怎么也去重不了。
select distinct name,age from emp; # 针对上述问题,需要这样去重,有点联合唯一的感jio!
select distinct age from emp; # 去重可以随意指定字段的多少。
7、order by排序
# 基础
select * from emp order by salary asc; # 默认采用升序,asc可以省略
select * from emp order by salary desc; # 降序
# 进阶
先按照age降序排,如果碰到age相同,再按照salary升序排
select * from emp order by age desc,salary asc; # salary后面还可以加,应付salary相同的情况!
8、limit限制展示条数
针对数据过多的情况,我们都是做分页处理!
select * from emp limit 3; # 只展示三条数据
select * from emp limit 0,5; # 只展示从第一条数据开始的五条数据
select * from emp limit 5,5; # 只展示从第六条数据开始的五条数据
第一个参数是起始位置
第二个参数是展示条数
9、正则
select * from emp where name regexp '^j.*(n|y)$';
10、连表操作
create table dpm( # 创建部门表
dpm_id int primary key auto_increment,
dpm_name varchar(20) not null unique
);
create table stuff( # 创建员工表
stuff_id int primary key auto_increment,
stuff_name varchar(20) not null unique,
stuff_age int not null,
stuff_gender enum('male','female'),
dpm_id int not null,
foreign key(dpm_id) references dpm(dpm_id)
on delete cascade
on update cascade
);
insert into dpm(dpm_name) values ('运维部'), ('技术部'), ('测试部'), ('财务部'), ('售后部');
MariaDB [db1]> select * from dpm;
+--------+-----------+
| dpm_id | dpm_name |
+--------+-----------+
| 5 | 售后部 |
| 2 | 技术部 |
| 3 | 测试部 |
| 4 | 财务部 |
| 1 | 运维部 |
+--------+-----------+
insert into stuff(stuff_name,stuff_age,stuff_gender,dpm_id) values ('吴晋丞',18,'male',1),('徐浩波',80,'male',2),('李丹',30,'female',4),('陈果',18,'male',5),('李青松',18,'male',3),('邓小龙',30,'male',5),('陈媛媛',21,'female',4);
MariaDB [db1]> select * from stuff;
+----------+------------+-----------+--------------+--------+
| stuff_id | stuff_name | stuff_age | stuff_gender | dpm_id |
+----------+------------+-----------+--------------+--------+
| 1 | 吴晋丞 | 18 | male | 1 |
| 2 | 徐浩波 | 80 | male | 2 |
| 3 | 李丹 | 18 | female | 4 |
| 4 | 陈果 | 18 | male | 5 |
| 5 | 李青松 | 18 | male | 3 |
| 6 | 邓小龙 | 30 | male | 5 |
| 7 | 陈媛媛 | 21 | female | 4 |
+----------+------------+-----------+--------------+--------+
查询平均年龄大于20岁的部门:
多表查询有两种方法可以解决:
(1)联表操作
select dpm_name from stuff inner join dpm
on stuff.dpm_id = dpm.dpm_id
group by dpm_name
having avg(stuff_age) > 20;
# 结果
+-----------+
| dpm_name |
+-----------+
| 售后部 |
| 技术部 |
+-----------+
(2)子查询
select dpm_name from dpm where dpm_id in
(select dpm_id from stuff group by dpm_id
having avg(stuff_age) > 20);
# 结果:
+-----------+
| dpm_name |
+-----------+
| 售后部 |
| 技术部 |
+-----------+
(3)内连接、左连接、右连接区别
还有一个union(全连接)就是左连接和右连接的并集,几乎很少用,故不讲!
inner join(内连接)
产生的结果是AB的交集(不会有null出现):
A left join B (左连接)
产生表A的完全集,而表B中匹配的则有值,没有匹配的则以null值取代.
左连接,就是从A表看起走,如果外键不为空,则有值,外键如果为空,那么dpm中就用null表示
因为我这里限制了stuff中的dpm_id不为空,因此这里的结果永远都和等值连接的结果一样!
A right join B (右连接)
产生表B的完全集,而表A中匹配的则有值,没有匹配的则以null值取代
售前部没有人,因此dpm产生完全集,stuff中没有匹配的员工,因此全用null取代!
右连接就是,从B表看起走,通过被外键约束的dpm_id,找有没有相应的员工,没有则,null值代替。
11、exist(了解)
只返回True False,返回True的时候外层查询语句执行,返回False的时候外层查询语句不得执行!
select * from emp where exists (select id from emp where id > 10);
如果括号中的语句执行后有数据,那么返回True,外层语句执行。
如果括号中的语句执行后无数据,那么返回False,外层语句不执行。
更多推荐
所有评论(0)