数据库之表查询,单表、多表,子查询
基本查询语句及方法
from
where
group by
having
distinct
order by
limit
....
连表
inner join
left join
right join
union
子查询
书写顺序
select id,name from emp where id > 3 and id < 6;
执行顺序
from # 确定到底是哪站表
where # 根据过来条件 筛选数据
select # 拿出筛选出来的数据中的某些字段
select * from emp\G; 当表字段特别多的时候 结果的排版可能会出现混乱的现象 你可以在查询语句加\G来规范查询结果
# 1.查询id大于等于3小于等于6的数据
select * from emp where id >= 3 and id <= 6;
select * from emp where id between 3 and 6;
上述语句完全等价
# 2.查询薪资是20000或者18000或者17000的数据
select id,name from emp where salary = 20000 or salary = 18000 or salary = 17000;
select id,name from emp where salary in (20000,18000,17000);
# 3.查询员工姓名中包含o字母的员工姓名和薪资
模糊匹配 like
%:匹配多个任意字符
_:匹配一个任意字符
select name,salary from emp where name like '%o%';
# 4.查询员工姓名是由四个字符组成的员工姓名与其薪资
select name,salary from emp where name like '____';
# 5.查询id小于3或者大于6的数据
select * from emp where id < 3 or id > 6;
select * from emp where id not between 3 and 6;
# 6.查询薪资不在20000,18000,17000范围的数据
select id,name from emp where salary not in (20000,18000,17000);
# 7.查询岗位描述为空的员工名与岗位名 针对null判断的时候只能用is 不能用=
select name,post from emp where post_comment = Null;
select name,post from emp where post_comment is Null;
MySQL对大小写不敏感
group by 分组
# 1.按部门分组
select * from emp group by post;
分组之后应该做到最小单位是组,而不应该再展示组内的单个数据信息
MySQL中分组之后 只能拿到分组的字段信息 无法直接获取其他字段信息
但是你可以通过其他方法(聚合函数)简介的获取
如果你的MySQL不报错 说明严格模式没有设置
show variables like '%mode%';
set session 当前窗口有效
set global 全局有效
set global sql_mode="strict_trans_tables,only_full_group_by";
select * from emp group by post;
select id,name from emp group by post;
select name from emp group by post;
# 2.获取每个部门的最高工资 聚合函数 max min avg sum count
select post,max(salary) from emp group by post;
给字段取别名
select post as '部门',max(salary) as '最高工资' from emp group by post;
select post '部门',max(salary) '最高工资' from emp group by post;
# 每个部门的最低工资
select post,min(salary) from emp group by post;
# 每个部门的平均工资
select post,avg(salary) from emp group by post;
# 每个部门的工资总和
select post,sum(salary) from emp group by post;
# 每个部门的人数
select post,count(age) from emp group by post;
select post,count(salary) from emp group by post;
select post,count(id) from emp group by post;
select post,count(post_comment) from emp group by post;
在统计分组内个数的时候 填写任意非空字段都可以完成计数,推荐使用能够唯一标识数据的字段
比如id字段
"""
聚合函数会自动将每一个分组内的单个数据做想要的计算,无需你考虑
"""
# 3.查询分组之后的部门名称和每个部门下所有的学生姓名
select post,group_concat(name) from emp group by post;
select post,group_concat('DSB',name) from emp group by post;
group_concat()能够拿到分组后每一个数据指定字段(可以是多个)对应的值
select post,group_concat(name,": ",salary) from emp group by post;
concat
select concat("NAME: ",name),concat("SAL: ",salary ) from emp;
小技巧:
concat就是用来帮你拼接数据
concat 不分组情况下使用
group_concat 分组之后使用
# 查询每个员工的年薪
select name,salary*12 from emp;
# 刚开始查询表,一定要按照最基本的步骤,先确定是哪张表,再确定查这张表也没有限制条件,再确定是否需要分类,最后再确定需要什么字段对应的信息
""" +
你应该将每一步操作产生的结果都当成是一张新的表
然后基于该表再进行其他的操作
"""
1. 查询岗位名以及岗位包含的所有员工名字group_concat
2. 查询岗位名以及各岗位内包含的员工个数count
3. 查询公司内男员工和女员工的个数count
4. 查询岗位名以及各岗位的平均薪资avg
5. 查询岗位名以及各岗位的最高薪资max
6. 查询岗位名以及各岗位的最低薪资min
7. 查询男员工与男员工的平均薪资,女员工与女员工的平均薪资avg
"""
聚合函数 max min sum count avg只能在分组之后使用
如果一张表没有写group by默认所有的数据就是一组
"""
书写顺序
select
from
where
group by
执行顺序
from
where
group by
select
8、统计各部门年龄在30岁以上的员工平均工资
# 先获取年轻在30岁以上的员工
select post,avg(salary) from emp where age > 30 group by post;
"""
写sql语句的时候 一定不要一口气写完
前期先按照步骤一步步写
写一步查询看一下结果然后基于当前结果再往后写
"""
having
跟where是一模一样的 也是用来筛选数据
但是having是跟在group by之后的
where是对整体数据做一个初步的筛选
而having是对分组之后的数据再进行一次针对性的筛选
1、统计各部门年龄在30岁以上的员工平均工资,
并且保留平均工资大于10000的部门
select post,avg(salary) from emp where age > 30 group by post having avg(salary) > 10000;
select post,avg(salary) from emp where age > 30 group by post where avg(salary) > 10000; # 报错
# 强调:having必须在group by后面使用
select * from emp having avg(salary) > 10000; # 报错
执行顺序
from
where
group by
having
select
distinct去重
多重复的数据进行一个去重
"""
去重必须数据是一模一样的才能去重
只要有一个不一样 都不能算是的重复的数据
"""
select distinct id,age from emp;
执行顺序
from
where
group by
having
select
distinct
order by 排序
默认是升序 asc
也可以变成降序 desc
select * from emp order by salary;
select * from emp order by salary asc;
select * from emp order by salary desc;
select * from emp order by age,salary; # 先按照age做升序 age相同的情况下再按照salary做升序
select * from emp order by age asc,salary desc; # 先按照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);
limit 限制展示数据的条数
select * from emp limit 5; # 只展示数据的五条
select * from emp limit 5,5;
"""
当limit只有一个参数的时候 表示的是只展示几条
当limit有两个参数的时候 第一个参数表示的起始位置 第二个参数表示从起始位置开始往后展示的条数
"""
# 查询工资最高的人的详细信息
# 先按照薪资排序
# 再用limit限制 只取一条
select * from emp order by salary desc limit 1;
# 在编程中 只要看到reg开头的 基本上都是跟正则相关
正则
select * from emp where name regexp '^j.*(n|y)$';
zhang
jssdsdsay
jy
jnn
多表查询
"""
表查询分为两大类
1.联表查询
2.子查询
"""
select * from emp,dep; 产生的结果是一个笛卡尔积
# 查询部门为技术部的员工及部门信息
有专门帮你做连表的方法
内连接(inner join)
左连接(left join)
右连接(right join)
全连接(union) # 只要将左连接和右连接的sql语句 加一个union就变成全连接
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;
子查询
将一张表的查询结果作为另外一个sql语句的查询条件
select name from dep where id = (select dep_id from emp where name = 'zhang');
# 2.每个部门最新入职的员工
# 思路:先查每个部门最新入职的员工,再按部门对应上联表查询
select t1.id,t1.name,t1.hire_date,t1.post,t2.* from emp as t1
inner join
(select post,max(hire_date) as max_date from emp group by post) as t2
on t1.post = t2.post
where t1.hire_date = t2.max_date
;
# 可以给表起别名
# 可以给查询出来的虚拟表起别名
# 可以给字段起别名