select [字段1,字段2...] from [表名]
where [条件]
group by [字段]
having [分组后的过滤条件]
order by [排序字段+顺序]
limit [显示条数];
关键字的优先级是帮助你正确且高效查询数据的前提, 需要重点了解
关键字有些可写, 有些可不写, 需要我们自己灵活运用, 下面将介绍使用方法, 派大星gogogo…
create table emp(
id int primary key auto_increment,
emp_name varchar(16) not null,
sex enum("male","female") default "male",
age int unsigned not null,
entry_date date not null,
post varchar(20),
post_des varchar(100) default "暂无说明...",
salary float(10,2),
office int,
dep_id int
);
insert emp(emp_name,sex,age,entry_date,post,salary,office,dep_id) value
("shawn","male",23,'20190804','TE',5100.5,324,1), # 测试工程师
('start','male',18,'20170301','TE',7300.33,401,1),
('Ann','male',78,'20150302','TE',1000000.31,401,1),
('Bella','male',81,'20130305','TE',8300,401,1),
('tony','male',73,'20140701','TE',3500,401,1),
('Alice','male',28,'20121101','TE',2100,401,1),
('jack','female',18,'20110211','ST',9000,401,2), # 系统工程师
('Cara','male',18,'19000301','ST',30000,401,2),
('Hedy','male',48,'20101111','ST',10000,401,2),
('Dora','female',48,'20150311','ST',3000.13,402,2),
('Sam','female',38,'20101101','ST',2000.35,402,2),
('Otis','female',18,'20110312','CFT',1000.37,402,3), # 程式测试工程师
('Ray','female',18,'20160513','CFT',3000.29,402,3),
('Chris','female',28,'20170127','CFT',4000.33,402,3),
('Summer','male',28,'20160311','CFT',10000.13,403,3),
('Rub','male',18,'19970312','CFT',20000,403,3),
('Luck','female',18,'20130311','HR',19000,403,4), # 人力资源
('Bob','male',18,'20150411','HR',18000,403,4),
('Tom','female',18,'20140512','HR',17000,403,4);
准备工作好了, 下面依次来介绍关键字的用法
这个比较简单, 就是你想看那张表的数据, from 后面接一个表名
select * from t01;
设置条件, 对符合条件的数据放行, 未设置默认true,全部通过
select * from emp where id>=2 and id<=4; # id 2~4 之间的员工闭区间
select * from emp where salary<4000; # 薪资小于 4000 的
select * from emp where (age between 77 and 82); # 年龄在 77~82 之间的,闭区间(括号可以省略)
select * from emp where (age in (81,73,23,58)); # 年龄在给定值之内的员工
select * from emp where not salary>4000; # 薪資不大于 4000 的员工
select * from emp where post='HR' or age in (81,73); # 岗位"HR"或者年龄是指定的员工
is null : 空
is not null : 非空
insert emp(emp_name,sex,age,entry_date,post,salary,office) value
("shawn","male",23,'20190804','TE',5100.5,324); # 表里面没有 null 的记录, 我们模拟一条
select * from emp where dep_id is null; # 部门编号为空的员工
select * from emp where post is not null; # 岗位不为空的员工
like [符号]
select * from emp where emp_name like "s%"; # 匹配以 "s" 开头的员工(不区分大小写)
select * from emp where emp_name like "_a%"; # 匹配第二个字母为 "a" 的员工
select * from emp where emp_name like "%r%"; # 匹配名字中含有 "r" 的员工
select * from emp where emp_name like "___"; # 匹配名字中有三个字符的员工
正则表达式的使用更加强大和灵活, 它是各种语言通用的强大工具, 前面写过一篇关于正则使用的博客
regexp [正则字符]
select * from emp where emp_name regexp "^s"; # 匹配"s"开头名字的员工
select * from emp where emp_name regexp "b$"; # 匹配"b"结尾名字的员工
select * from emp where emp_name regexp ".*mm.*"; # 匹配含有"mm"字符名字的员工
group by 分组在 where 过滤之后执行
目的是为了统计分析每个组内的数据信息, 比如部门人数、岗位人数、男人数、女人数、平均薪资、平均年龄等
聚合函数后边可用
as
来取别名 :max(xxx) as [别名]
, 也可以省略as
, 例如 :max(xxx) [别名]
, 还可以为表取别名 :...emp as t01
, 但是得注意, 表别名之后, 使用表名也就换成了表别名
select * from emp group by post; # 以部门为分组字段(没有设置严格模式,会取每一个部门的第一个员工)
select post from emp group by post; # 指定字段不会出现上面的情况
set sql_mode='strict_trans_tables,only_full_group_by'; # 设置严格模式+追加分组严格模式
select * from emp group by post; # 设置严格模式之后再使用这种方式直接报错
select post from emp group by post; # 还是指定字段分组
max( )
select post,max(age) as max_age from emp group by post;
min( )
select age,min(salary) as min_salary from emp group by age;
avg( )
select post,avg(salary) from emp group by post;
sum( )
select post,sum(age) as age_sum from emp group by post;
count( )
select post,count(id) as post_people from emp group by post;
# count( ) 函数最好使用可以表示唯一性的字段,入所演示的 id 就是唯一性的字段(当然其他字段也可以)
# 特别注意的是不能使用有 null 关键字的字段
group_concat( )
select post,group_concat(emp_name) from emp group by post;
select post,group_concat(emp_name,"_haha") from emp group by post;
select post,group_concat(emp_name,":",salary) from emp group by post;
concat( )
: 注意, 这个是不分组时使用的拼接函数select concat("name:",emp_name),concat("age:",age) from emp where id>10;
select concat("name:",emp_name," post:",post) from emp where age>23;
concat_ws([指定的分隔符], [字段1],[字段2]...)
select concat_ws(":",emp_name,age,sex) from emp where id between 6 and 11;
select concat_ws("-",emp_name,post,salary) from emp where age in (23,28,73,81);
case
语句伪代码
case when [条件1] then [结果]
when [条件2] then [结果]
...
else [结果]
end
示例:
#查找薪资大于 10000 的员工, 并对其信息进行拼接 id+姓名---NB+sex, 小于的 id+姓名---loser+sex
select
case
when salary>10000 then
concat_ws(":",id,emp_name,"----NB",sex)
else
concat_ws(":",id,emp_name,"----loser",sex)
end
as info
from emp;
聚合函数必须在分组后使用, 不分组默认整张表就是一组
having 是在 group by 之后的筛选操作
select post,group_concat(emp_name,":",salary) as info from emp
where id>6
group by post
having avg(salary)>10000;
select post,group_concat(emp_name),count(id) from emp
group by post
having count(id)>2;
select post,avg(salary) from emp
group by post
having avg(salary)>10000;
distinct
一般是用来去除查询结果中的重复记录的
完全一样的数据才可以去重, 去重时应略过主键(非空且唯一)和设置了 unique 字段
select distinct age from emp; # 只对一列进行操作
select distinct age,salary from emp; # 对多列进行操作, 多列去重
distinct
只能放在所有字段前面select age,distinct salary from emp; # 错误语法,报错
asc
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 desc; # 先age升序,如果有age相同的员工,再进行薪资降序
select post,avg(salary) from emp
where age>17
group by post
having avg(salary)>5000
order by avg(salary) desc;
select post,avg(salary) as avg_salary,group_concat(emp_name,":",age) from emp
where age>17
group by post
having avg(salary)>5000
order by avg_salary desc; # select的优先级大于 order by, 而as是在select这里别名的, 所以在order这里需要使用别名
limit 2,5
: 第一个参数是起始位置, 第二个参数是展示的条数(只有一个参数代表值展示指定条数数据)select * from emp limit 5; # 值展示5条记录
select * from emp limit 2,5; # 从第2条记录开始往后取5条记录
----end----