MySQL查找关键字
目录
内容概要
-
SQL语句查询关键字
select from where group by # 分组 having # 分组前用where 分组后用 having distinct # 去重 order by # 排序 limit # 可以一次性展示几条数据 和 可以从自定义从 那开始展示 regexp # 正则 -
多表查询的两种方式
- 子查询
- 连表操作
SQL语句查询关键字
-
select
select 指定需要查询的字段信息 select * 查询所有字段 select name 查询name字段 select char_length(name) 支持对字段做处理 from 指定需要查询的表信息 from t1 from mysql.user SQL语句中关键字的执行顺序和编写顺序不一致 可能会错乱 eg: select id,name from info; 我们先写的select 再写的from 但是执行的时候会先去执行from找到这张表 在去执行select 去查询这张表 ps:会写sql 即可 没必要管他先执行还是后执行前期数据准备
create table emp( id int primary key auto_increment, name varchar(20) not null, gender enum('male','female') not null default 'male', #大部分是男的 age int(3) unsigned not null default 28, hire_date date not null, post varchar(50), post_comment varchar(100), salary double(15,2), office int, #一个部门一个屋子 depart_id int ); #插入记录 #三个部门:教学,销售,运营 insert into emp(name,gender,age,hire_date,post,salary,office,depart_id) values ('jason','male',18,'20170301','浦东第一帅形象代言',7300.33,401,1), #以下是教学部 ('tom','male',78,'20150302','teacher',1000000.31,401,1), ('kevin','male',81,'20130305','teacher',8300,401,1), ('tony','male',73,'20140701','teacher',3500,401,1), ('owen','male',28,'20121101','teacher',2100,401,1), ('jack','female',18,'20110211','teacher',9000,401,1), ('jenny','male',18,'19000301','teacher',30000,401,1), ('sank','male',48,'20101111','teacher',10000,401,1), ('哈哈','female',48,'20150311','sale',3000.13,402,2),#以下是销售部门 ('呵呵','female',38,'20101101','sale',2000.35,402,2), ('西西','female',18,'20110312','sale',1000.37,402,2), ('乐乐','female',18,'20160513','sale',3000.29,402,2), ('拉拉','female',28,'20170127','sale',4000.33,402,2), ('僧龙','male',28,'20160311','operation',10000.13,403,3), #以下是运营部门 ('程咬金','male',18,'19970312','operation',20000,403,3), ('程咬银','female',18,'20130311','operation',19000,403,3), ('程咬铜','male',18,'20150411','operation',18000,403,3), ('程咬铁','female',18,'20140512','operation',17000,403,3);
编写SQL语句的小技巧
针对
select后面的字段名可以先用*占位往后写 最后在回来修改在实际应用中
select后面很少跟*因为*表示所有 当中字段和数据都特别多的情况下非常浪费数据资源""" SQL语句的编写类似于代码的编写 不是一蹴而就的 也需要反反复复的修修补补 """查询关键字之where筛选
-
查询id大于等于3 小于等于6的数据
select * from emp where id >=3 and id<=6; select * from emp where between 3 and 6;

-
查询薪资是20000或者18000或者17000的数据
select * from emp where salary=20000 or salary=18000 or salary=17000; select * from emp where salary in (20000,17000,18000);
-
查询id小于3大于6的数据
select * from emp where not (id >= 3 and id <= 6); """ 如果不加括号 只打印 小于3 的数据 """ select * from emp where id < 3 or id >6; select * from emp where not between 3 and 6;



-
查询员工姓名中包含字母
o的员工姓名与薪资条件不够精确的查询 称之为 模糊查询 模糊查询的关键字 是 like 模糊查询的常用符号 %: 匹配任意个数的任意字符 _: 匹配单个个数的任意字符 select * from emp where name like '%o%';
select * from emp where name like '_o'; 只能匹配 jo ao wo 啊这种的 名字 只有两个字符 且 是 什么 o 的形式 而 %o 是以o结尾的 o% 是以o开头的 -
查询员工姓名是由四个字符组成的员工姓名与其薪资
select name,salary from emp where name like '____'; select name, salary from emp where char_length(name) = 4;

-
查询岗位描述为空员工与岗位名 针对null不能用等号,只能用is
select * from emp where post_comment=NULL; 不可以 select * from emp where post_comment is NULL;
NULL 是一个关键字 你写成 'NULL' 也没用
必须要用 is
-
查询关键字之group by分组
-
分组:按照指定的条件将单个的数据组成一个个整体
eg:
将班级学生按照性别分组
将一些 花朵 按照颜色分组
~~~~ 按照花瓣的个数分组
等等
-
分组的目的是为了更好的同级相关数据
eg:
每个班级的男女比例
每个部门的平均薪资
-
需要结合一些
聚合函数专门用于分组之后的数据统计
max\ min\ sum\ avg\ count 最大 最小 求和 平均 计数
-
将员工数据按照部门分组
select * from emp group by post; """ MySQL5.6默认不会报错 set global sql_mode='strict_trans_tables,only_full_group_by' MySQL5.7及8.0默认会直接报错 原因是分组之后 select 后面只能直接写 分组的一句 不能再写其他字段 select post from emp group by post; select age from emp group by age; 分组之后默认最小的单位应该就是组 而不是组内的其他单个字段 也就是 分组 只能显示 按什么分组的字段 不能是其他字段 想要看到其他字段用 聚合函数 """ 严格模式没有 修改时
修改后
-
获取每个部门的最高工资、
""" 要不要分组我们完全可以从题目的需求的分析出来尤其时出现关键字 每个 平均 """ select post as '部门',max(salary) as '平均工资' from emp group by post; 针对 sql语句执行之后的结果 我们是可以修改字段名称的 关键字也可以省略 select post '部门' from emp group by post;

""" 但是不推荐 省略关键字 as 省略了就没有那么见名知意了 """ -
一次获取部门的相关统计(最高薪,最低薪,平均薪,月支出)
select post as '部门',max(salary)as '最高薪',min(salary)as '最低薪', avg(salary)as '平均薪',sum(salary)as'月支出' from emp group by post;
-
统计每个部门的部门名称以及部门下的员工姓名
""" 分组以外的字段无法直接填写 需要借助于方法 """ select post , name from emp group by post; 报错
select post, group_concat(name) from emp group by post; select post,group_concat(name,age) from emp group by post; select post,group_concat(name,"|",age) from emp group by post; select post,group_concat('DSB_',name) from emp group by post; select post, group_concat(name,'_NB') from emp group by post;

查询关键字之having过滤
having 与 where 的本质一样
只是 where 用在 group by 之前(首次过滤)
having 用在 分组之后(二次过滤)
-
统计部门年龄在30岁以上的员工平均工资 并且保留大于10000的数据
""" 稍微复杂一点的SQL 跟写代码几乎一样 也需要提前想好大致思路 每条SQL的结果可以直接看成就是一张表 基于该表如果 还想继续操作则直接在产生该表的SQL语句上添加即可 """步骤一:先筛选出所有年龄大于30岁的员工数据 select * from emp where age >30 步骤二: 在对筛选出的数据按照部门分组并统计平均薪资 select post as '部门',avg(salary) as '平均薪资' from emp group by post; 步骤三: 在筛选出 平均薪资大于1000的
查询关键字之distinct去重
去重有一个必须的条件也是很容易被忽略的条件
数据必须一摸一样才可以去重
select distinct id, age from emp; # 关键字针对的是多个字段组合的结果
select distinct age from emp;
select distinct age,post from emp;



查询关键字之order by 排序
1.可以单个字段排序
select * from emp order by age; # 默认升序
select * from emp orger by age asc; # 默认升序(asc可以省略)
select * from emp orger by age desc; # 变成降序
2.也可以是多个字段排序
select * from emp orger by age, salary desc;
先按age 排序 如果 age里有一样 那些一样的数据 按salary 降序排



统计各部门 年龄 在10岁以上的员工平均工资,并且保留平均工资大于1000的部门,然后对平均工资进行排序
1.先筛选出所有年龄大于10岁的员工
select * from emp where age > 10;
2.在对他们按照部门分组统计平均工资
select post,avg(salary) from emp where age > 10 group by post
3.针对分组的结果做二次筛选
select post,avg(salary) from emp where age > 10 group by post having avg(salary) > 1000
4.最后按指定字段排序
select post,avg(salary) from emp where age > 10 group by post having avg(salary) > 1000 order by avg(salary);
"""
当一条SQL与酒很多地方都需要使用的聚合函数计算之后的结果 我们可以节省操作(主要节省了底层运行效率 代码看不出来)
select post,avg(salary) as 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 # 从第5体条开始 往后读5条


查询工资最高的人的详细信息
"""
千万不要 惯性思维 一看到最高就分组聚合
可以先按工资倒叙 然后再取第一条数据
"""
select * from emp order by salary desc limit 1;

查询关键字之regexp正则表达式
SQL语句的模糊匹配如果不习惯 也可以自己写正则批量查询
select * from emp where name regexp '^j.*?(n|y)$';
5.6 写法
select * from emp where name regexp '^j.*(n|y)$';
有问号直接报错


多表查询的思路
表数据准备
create table dep(
id int primary key auto_increment,
name varchar(20)
);
create table emp1(
id int primary key auto_increment,
name varchar(20),
gender enum('male','fmale') not null default 'male',
age int,
dep_id int
);
# 插入数据
insert into dep values
(200,'技术'),
(201,'人力资源'),
(202,'销售'),
(203,'运营'),
(205,'财务');
insert into emp1(name, gender,age,dep_id) values
('jason','male',18,200),
('dragon','fmale',48,201),
('kevin','male',18,201),
('nick','male',28,202),
('owen','male',18,203),
('jerry','fmale',18,204);
select * from emp,dep; 将所有的数据对应一遍
这个现象我们也称之为'笛卡尔积'无脑的对应没有意义 应该将有关系的数据对应到一起才合理
基于笛卡尔积可以将部门编号与部门id相同的数据筛选出来
涉及到两张表及以上的表是 字段很容易冲突 我们需要在字段前面加上表名来指定
select * from emp,dep where emp.deo_id = dep.id;


作业
2.完成下列基础练习题SQL编写
1. 查询岗位名以及岗位包含的所有员工名字
先按岗位分组
select post as '部门',group_concat(name) from emp group by post
在按岗位查询

查询岗位名以及各岗位内包含的员工个数
select post as '部门',count(id) as '人数' from emp group by post;

-
查询公司内男员工和女员工的个数
select gender as '性别',count(id) from emp group by gender;
-
查询岗位名以及各岗位的平均薪资
select post as '部门', avg(salary) as '平均薪资' from emp group by post;
-
查询岗位名以及各岗位的最高薪资
select post as '部门', max(salary) as '最高薪资' from emp group by post;
-
查询岗位名以及各岗位的最低薪资
select post as '部门', min(salary) as '最低薪资' from emp group by post;

-
查询男员工与男员工的平均薪资,女员工与女员工的平均薪资
select gender as '性别', avg(salary) as '平均薪资' from emp group by gender;
-
统计各部门年龄在30岁以上的员工平均工资
select post as '部门', avg(salary) as '平均薪资' from emp where age > 30 group by post; select post as '部门', avg(salary) as '平均薪资' from emp where age < 30 group by post;


浙公网安备 33010602011771号