一 单表查询的语法:
select 字段1 字段2... from 表名
where +条件
group by + field (分组)
having (筛选)
order by field ( 排序)
limit (限制条件)
二 关键字的执行优先级(重点)
关键字的执行优先级
顺序:
from # 找到表 from where #拿着where指定的约束条件,去文件/表中取出一条条记录 group by #将取出的一条条记录进行分组 group by,如果没有group by, 则整体作为一组 having #将分组的结果进行having 过滤 select #执行 select distinct # 去重 order by # 将结果按照条件进行排序 limit #限制结果的显示条数
三 查询
创建一个员工表 emp,查看表结构
插入数据:
查询表中所有的数据:
简单查询: from
select * from emp:* 是所有 也就查询来自这个emp的表格 所有的。如上图。
非所有的话 如姓名, 薪资 如下:
四:where 过滤 约束
where 字句中可以使用:
1:比较运算符:> 、<、 >=、<=、 <>、 !=
2: between .... and 在..... 之间。 (between 80 and 100) 值在80 到100 之间
3:in(80,90,100)值是80或90或100。
4: like 'egon%' 模糊映射 % 号处 可以是% 也可以是_, % 表时任意多个字符,_表示一个字符。
5.逻辑运算符: 在多个条件直接可以使用逻辑运算符 and not or
#查询:查询 部门是sale 的名字
select name from emp where post = 'sale';
#多条件查询 :查询部门是老师且薪资大于10000 的人的名字和薪资
select name,salary from emp where post='teacher' and salary>10000
# 查询薪资在10000 和20000 之间的员工的名字和薪资
select name,salary from emp where salary between 10000 and 20000;
# 要求查询员姓名中包含I 字母的员工姓名与其薪资
select name,salary from db3.emp where name like "%i%";
# 查询员工姓名是由四个字符组成的员工姓名与其薪资,有两种查询方式
第一种方式:
select name, salary from emp where name like '____';
第二种方式
select name,salary from emp where char_length(name)=4;
#查询员工id不在3-6 之间的员工信息名
select * from emp where id not between 3 and 6;
# 查询岗位描述为空的 员工名与岗位名
select name,post from db39.emp where post_comment is NULL;
五 分组 group by
为什么要分组
首先明确一点, 分组是发生在where之后, 即分组是基于 where之后 得到的记录而进行的
分组指的是将所有的记录按照某个相同字段进行归类, 如针对员工信息表的职位分组 或者按照性别进行分组等
为什么要分组呢
方便统计数据
取每个部门的最高工资
取每个部门的员工数
取男人数和女人数
需有个大前提
可以按照任意字段分组, 但是分组完毕后,比如group by post, 只能查看post字段吗如果想看组内信息 需要借助于聚合函数
单独使用group by 关键字分组 select post from emp group by post; 注意:我们按照post 字段分组, 那么select 查询的字段只能是post,想要获取组内的其他相关信息, 需要借助函数 group by 关键字和group_concat()函数一起使用 group by 与聚合函数一起使用
聚合函数 聚合的是组的内容, 若是没有分组, 则默认是一组
聚合函数 [ count(*)个数,max(*)最大值 , min(*)最小值, avg(*)平均值,sum(*)总和,]
强调:
如果我们用unique的字段作为分组的依据, 则每一条记录自成一组, 这种分组没有意义
多条记录之间的某个字段值相同,该字段通常用来作为分组的依据
练习
查询每个部门的员工名
select post,group_concat(name) from emp group by post;
在每个部门的员工名后+sb
select post,group_concat(name,'_sb') from emp group by post;
在name 后面加 :
select post,group_concat(name,':',salary) 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,sum(salary) from emp group by post ;
查询:每个部门的平均工资
select post,avg(salary) from emp group by post ;
统计每个部门的id数;
需要补充的是 concat (它是不分组是用),’
as 作为 可以起个别名。
select name as 姓名,salary as 薪资 from emp;
姓名和薪资前加上字段
select concat (‘NAME:’,name)as 姓名,concat('SAL:',salary)as 薪资 from emp;
四则运算
查询员工的年薪
select name,salary*12 as annual_salary from emp;
六 having 过滤
having的语法格式与where一毛一样,只不过having 是在分组之后进行的进一步过滤
即where不能用聚合函数 而having是可以用聚合函数, 这也是他们俩最大的区别
执行优先级从高到低, where> group by >having where 发生在分组group by之前 因而where中可以有任意字段, 但是对不不能使用聚合函数 having 发生在分组group by 之后 因而having中可以使用分组的字段 无法直接渠道其他字段 ,可以使用聚合函数
练习:
统计各部门年龄在30岁以上的员工平均工资,并且保留平均工资大于10000的部门
select post, avg(salary) from emp where age >= 30 group_by post having avg(salary)>10000;
强调 having 必须在group by 后面使用,
select * from emp having avg(salary)>10000; # 没有写分组 默认为一组。
七: distinct 去重
语法是跟在 select 后面
统计员工年龄大于30,平均薪资大于10000的 部门
八 order by 排序
select * from emp order by salary asc 默认升序排序
selec * from emp order by salary desc 降序排
select* from emp order by age desc 降序排
selec * from emp order by age desc,salary asc 先按照 age 降序排,当age相同时 在按照薪资升序排
统计各部门年龄在10岁以上的员工平均工资,并且保留平均工资大于1000的部门,
然后对平均工资进行排序
#select post,avg(salary) from emp where age>=10 group by post having avg(salary)>10000 order by avg(salary);
九 limit 限制显示条数, 可以用它来分页
练习:显示三条信息
分页练习
分页表示的是从0开始 显示5条, 从5开始显示5条。如下:
十 正则表达式
查询 员工名以jin开头, 以n 或g 结尾所有员工名
select * from emp where name regexp '^jin.*(n|g)$';