1 补充
# 当表的字段特别多,屏幕展示不下,因此会格式错乱,这个时候可以采用G分行展示。
ex: select * from empG;
# 某些Windows电脑在插入中文的时候,即使已经修改了配置文件,但是还是会出现乱码的情况,这个时候就只能使用GBK了。。。
2 关键字的执行顺序
# 书写顺序
select id, name from emp where id > 3;
# 执行顺序
from
where
select
3 where 筛选条件
# 作用:是对整体数据的一个筛选操作
# 1、查询id >= 3 and id <= 6的数据
select id, name, age from emp where id >= 3 and id <= 6;
select id, name, age from emp where id between 3 and 6; # 以上两种写法等价
# 2、查询薪资是20000或者18000或者17000的数据
select * from emp where salary = 20000 or salary = 18000 or salary = 17000;
select * from emp where salary in (20000, 18000, 17000);
# 3、查询员工姓名中包含字母o的员工的姓名和薪资
select name, salary from emp where name like '%o%';
# 4、查询员工姓名是由4个字符组成的姓名和薪资
select name, salary from emp where name like '____';
select name, salary from emp where char_length(name) = 4;
# 5、查询id < 3或者id > 6的数据
select * from emp where id not between 3 and 6;
select * from emp where id < 3 or id > 6;
# 6、查询薪资不在20000、18000、17000范围的数据
select * from emp where salary not in (20000, 18000, 17000);
# 7、查询岗位描述为空的员工姓名和岗位名,针对null不可以用“=”,而是要用is
select name, post from emp where post_comment is null;
4 group by 分组
# 分组的实际应用场景非常多,例如
男女比例
部门平均薪资
国家之间数据比较
# 1、按照部门分组
select * from emp group by post;
# 分组之后,最小可操作单位应该是组,而不是组内的单个数据
# 上述命令在没有设置严格模式的时候是可以正常运行的,返回的是分组之后每一组的第一条数据,但是这不符合分组的规范:分组之后不应该考虑单个数据,而应该以组为操作单位(分组之后没办法直接获取组内单个数据)
# 如果设置了严格模式,那么上述命令就会直接报错!!!
set global sql_mode = 'STRICT_TRANS_TABLES,ONLY_FULL_GROUP_BY';
设置严格模式之后,分组默认只能拿到分组的依据
select * from emo group by post; # 按照什么分组就只能拿到什么分组,其他字段不能直接获取,需要借助于一些方法,这些方法也就是聚合函数(max、min、avg、sun、count)
# 什么时候需要分组啊???
当看见关键字:每个、平均、最高、最低的时候就要考虑分组问题
# 1、获取每个部门的最高薪资
select post, max(salary) from emp group by post;
select post as '部门', max(salary) as '最高薪资' from emp group by post;
# 2、获取每个部门的最低薪资
select post, min(salary) from emp group by post;
# 3、获取每个部门的平均薪资
select post, avg(salary) from emp group by post;
# 4、获取每个部门的薪资总和
select post, sum(salary) from emp group by post;
# 5、获取每个部门的人数
select post, count(id) from emp group by post;
select post, count(salary) from emp group by post; # 也可以,但是推荐使用id字段,语义明确
select post, count(null) from emp group by post; # 错误!!!不可以统计null
# 6、查询分组之后的部门名称以及每个部门下所有的员工姓名
# 方法:获取分组之后单个字段的值:group_concat(name),不单单可以支持获取分组之后的其他字段的值,还支持拼接操作
select post, group_concat(name) from emp group by post;
select post, group_concat(name, ':', salary) from emp group by post;
# concat不分组的时候用
select concat('NAME: ', name), concat('SAL: ', salary) from emp;
# 总结:用于字符串拼接的两种方法
# 分组之后:group_concat()
# 分组之前:concat()
# 补充:as语法不单单可以给字段起别名,还可以给表临时起别名
select emp.id, emp.name from emp;
select t1.id, t1.name from emp as t1;
# 查询每个人的年薪,12薪
select name, salary * 12 from emp;
5 分组注意事项
# 1、关键字where和group by同时出现的时候,group by必须放在where的后面
# where先对整体数据进行过滤,之后在进行分组操作
# where筛选条件不能使用聚合函数,必须先分组才可以使用聚合函数,也就是where的后面不能直接跟聚合函数,但是如果有其他关键字可以用聚合函数,但是不能在where后面跟聚合函数。
select id, name, age from emp where max(salary) > 3000; # 这是错误的!!!
select max(salary) from emp; # 不分组,那么默认整体就是一组
# 统计各部门年龄在30岁以上的员工平均薪资
# 1、先求所有年龄大于30岁的员工
select * from emp where age > 30;
# 2、再对结果进行分组
select post, avg(salary) from emp where age > 30 group by post;
6 having 分组之后的筛选条件
# having的语法和where是一致的,只不过having是在分组之后进行的过滤操作
# 即having是可以直接使用聚合函数的
# 统计各部门年龄在30岁以上的员工的平均薪资并且保留平均薪资大于10000的部门
select post, avg(salary)
from emp
where age > 30
group by post
having avg(salary) > 10000;
7 distinct 去重
# 必须是完全一样的数据才可以去重!!!id往往都是不同的,进而导致无法去重
# 一定要注意,不要将主键忽略掉,有主键存在的情况下是不可能去重的
例如:
select distinct id, age from emp; # 带有id的时候无法去重
select distinct age from emp;
8 order by 排序
select * from emp order by salary; # 默认是升序排列asc
select * from emp order by salary desc; # desc代表降序排列
select * from emp order by age desc, salary asc; # 先按照age降序排列,如果age相同,则按照salary升序排列
# 统计各部门年龄在10岁以上的员工平均薪资并且保留平均薪资大于1000的部门,然后对平均薪资进行降序排序
select post, avg(salary)
from emp
where age > 10
group by post
having avg(salary) > 1000
order by avg(salary) desc;
9 limit限制展示条数
select * from emp limit 3; # 只展示3条数据
# 针对数据过多的情况,我们通常做分页处理,为了防止数据量过大导致系统死机的情况
select * from emp limit 0, 5;
# 第一个参数是起始位置,第二个参数是条数
10 正则
select * from emp where name regexp '^j.*(n|y)$'; # 以j开头,以n或者y结尾,.*代表任意多个字符
11 多表操作
11.1 表查询
select * from dep, emp; # 结果是笛卡尔积
select * from emp, dep where emp.dep_id = dep.id; # 忘记这种方式,不推荐使用,语义不明确。
# MySQL给我们开设了对应的方法
inner join # 内连接
left join # 左连接
right join # 右连接
union # 全连接
# 内连接:只拼接两张表中共有的数据部分
select * from emp inner join dep on emp.dep_id = dep.id;
# 左连接:展示左边表所有的数据,右边表没有对应的项就用null填充
select * from emp left join dep on emp.dep_id = dep.id;
# 右连接:展示右边表所有的数据,左边表没有对应的项就用null填充
select * from emp right join dep on emp.dep_id = dep.id;
# 全连接:展示左右两表所有的数据都展示出来
select * from emp left join dep on emp.dep_id = dep.id union select * from emp right join dep on emp.dep_id = dep.id;
11.2 子查询
# 子查询就是我们平时解决问题的思路
# 分步骤解决问题
第一步
第二步
···
# 将一个查询语句的结果当作另外一个查询语句的条件去用
# ex:查询部门是技术或者人力资源的员工信息
我们的思路:
1、先获取部门的id号
2、再去员工表里筛选出对应的员工信息
select id from dep where name = '技术' or name = '人力资源';
select * from emp where dep_id in (200, 201);
# 整合
select * from emp where dep_id in (select id from dep where name = '技术' or name = '人力资源');