单表查询

北城以北 提交于 2019-11-28 04:12:23

单表查询

前期表准备

create table emp(
    id int not null unique auto_increment,
    name varchar(20) not null,
    sex 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,sex,age,hire_date,post,salary,office,depart_id)
values
("jaosn","male",18,"20170301","张江第一帅形象代言",7300.33,404,1),
("egon","male",78,"20150302","teacher",1000000.31,401,1),
("kevin","male",81,"20130305","teacher",8300,401,1),
("tank","male",73,"20140701","teacher",3500,401,1),
("owen","male",28,"20121101","teacher",2100,401,1),
("jerry","female",18,"20110211","teacher",9000,401,1),
("nick","male",18,"19000301","teacher",30000,401,1),
("sean","male",48,"20101111","teacher",10000,401,1),

("歪歪","female",48,"20150311","sale",3000.13,402,2),
("丫丫","female",38,"20110312","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),
("程咬银","male",18,"20130311","operation",19000,403,3),
('程咬铜',"male",18,"20150411","operation",18000,403,3),
("程咬铁","female",18,"20140512","operation",17000,403,3)
;

# ps:如果在window系统中,插入中文字符,select的结果为空白,可以将所有字符编码统一设置成gbk

1.语法执行顺序

书写顺序
select id,name from emp where id > 3 and id < 6;
执行顺序
from  # 确定到底是哪张表
where  # 根据条件,筛选数据
select  # 取出筛选出来的数据中的某些字段
select * from emp\G;  # 当表字段特别多的时候,结果的排版可能会出现混乱的现象,你可以在查询语句加\G来规范查询结果

2.where约束条件

# 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 * from emp where salary = 2000 or salary = 18000 or salary = 17000;
select * from emp where salary in (20000,17000,18000);


# 3.查询员工姓名中包含o字母的员工姓名和薪资
# 模糊匹配 like
    %:匹配多个任意字符
    _:匹配一个任意字符
select name,salary from emp where name like "%o%";


# 4.查询员工姓名是由四个字符组成的员工姓名与其薪资
select name,salary from emp where name like "____";
select name,salary from emp where char_length(name) = 4;


# 5.查询id小于3或者大于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 = NULL;  # 查询为空
select name,post from emp where post_comment is NULL;
select name,post from emp where post_comment is not NULL;  # 查询为空
# 注意:MySQL对大小不敏感

3.group by

MySQL中分组之后,只能拿到分组的字段信息,无法直接获取其他字段信息,但是可以通过其他方法(聚合函数)简介的获取。

1.count():计数,为null时不会计入

2.sum():求和

3.avg():求平均书,为null时不计入分母

4.max():求最大值

5.min():求最小值

以上聚合函数可以写在字段的位置,或则是分组的后面

# 数据分组应用场景:每个部门的平均薪资,男女比例


# 1.按部门分组
select * from emp group by post;  # 分组后取出的是每个组的第一条数据的字段
# 注意:分组之后应该做到最小单位是组,而不应该再展示组内的单个数据信息,此时我们可可以添加ONLY_FULL_GROUP_BY到sql_mode中避免这个问题
如果你的MySQL不报错,说明严格模式没有设置
show variables like "sql_mode"; 
set session 当前创口有效
set global sql_mode = "strict_trans_tables,only_full_group_by";
设置好之后
select * from emp group by post;  # 报错
select id,name,sex from emp group by post; # 报错
select post from emp group by post;  # 获取部门信息
# 强调:只要分组了,就不能够再"直接"查找到单个数据信息了,只要获取到组名


# 2.获取每个部门的最高工资
# 以组为单位统计组内数据>>>聚合查询(聚集到一起合成为一个结果)
# 每个部门的最高工资
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(id) 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(post_comment) from emp group by post;  # 人数为0
# 注意:在统计分组内个数的时候,填写任意非空字段都可以完成计数,推荐使用能够唯一标识数据的字段,比如id字段


# 3.查询分组之后的部门名称和每个部门下所有的学生姓名
# group_concat(分组之后用) 不仅可以用来显示除分组外字段还有拼接字符串的作用
select post,group_concat(name) from emp group by post;
select post,group_concat("DSB",name) from emp group by post;
select post,group_concat(name,":",salary) from emp group by post;
select post,group_concat(salary) from emp group by post;


# 4.补充concat(不分组时用)拼接字符串达到更好的显示效果  as语法使用
select name as 姓名,salary as 薪资 from emp;
select concat("NAME:",name) as 姓名,concat("SAL:",salary)
as 薪资 from emp;

# 补充as语法,即可以给字段起别名也可以给表起
select emp.id,emp.name from emp as t1;  # 报错,因为表名已经被改成了t1
select t1.id,t1.name from emp as t1;

# 查询四则运算
# 查询每个人的年薪
select name,salary*12 as annual_salary from emp;
select name,salary*12 as annual_salary from emp;  # as可以省略

刚开始查询表,一定要按照最基本的步骤,先确定是哪张表,再确定查这张表也没有限制条件,再确定是否需要分类,最后再确定需要什么字段对应的信息

你应该将每一步操作产生的结果都当成是一张新的表,然后基于该表再进行其他的操作

练习题

# 刚开始查询表,一定要按照最基本的步骤,先确定是哪张表,再确定查这张表也没有限制条件,再确定是否需要分类,最后再确定需要什么字段对应的信息

# 1.查询岗位名以及岗位包含的所有员工名字
select post,group_concat(name) from emp group by post;
# 2.查询岗位名以及各岗位内包含的员工个数
select post,count(id) from emp group by post;
# 3.查询公司内男员工和女员工的个数
select sex,count(id) from emp group by sex;
# 4.查询岗位名以及各岗位的平均薪资
select post,avg(salary) from emp group by post;
# 5.查询岗位名以及各岗位的最高薪资
select post,max(salary) from emp group by post;
# 6.查询岗位名以及各岗位的最低薪资
select post,min(salary) from emp group by post;
# 7.查询男员工与男员工的平均薪资,女员工与女员工的平均薪资
select sex,avg(salary) from emp group by sex;
# 8.统计各部门年龄在30岁以上的员工平均工资
select post,avg(salary) from emp where age > 30 group by post;

"""
写sql语句的时候,一定不要一口气写完,前期先按照步骤一步步写,写一步查询看一下结果然后基于当前结果再往后写
"""

4.having

having的语法格式与where一致,只不过having是在分组之后进行的过滤,即where虽然不能用聚合函数,但是having可以!

select 查询条件1,查询条件2,...from 表名
        where 过滤条件
        group by 分组依据

# 语法这么写,但是执行顺序却不一样
# 执行顺序
from 
where 
group
select
# 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;  # 报错

5.distinct 去重

去重必须是一模一样的才能去重,只要有一个不一样,都不能算是重复的数据。

# 对有重复的展示数据进行去重操作
select distinct post from emp;
select distinct id,age from emp;

执行顺序
from 
where
group by
having
select
distinct

6.order by 排序

默认是升序asc,也可以变成降序desc

select * from emp order by salary asc;  # 默认升序排
select * from emp order by salary desc; # 降序排

select * from emp order by age desc;  # 降序排

# 先按照age降序排,在年龄相同的情况下再按照薪资升序排
select * from emp order by age desc,salary asc;

# 统计各部门年龄在10岁以上的员工平均工资,并且保留平均工资大于1000的部门,然后对平均工资进行排序
select post,avg(salary) from emp
    where age > 10
    group by post
    having avg(salary) > 1000
    order by avg(salary)
    ;

7.limit 限制

limit 限制展示数据的条数

当limit只有一个参数的时候,表示的是只展示几条

当limit有两个参数的时候,第一个参数表示的是起始位置,第二个参数表示从起始位置开始往后展示的条数。

# 限制展示条数
select * from emp limit 3;
# 查询工资最高的人的详细信息
select * from emp order by salary desc limit 1;

# 分页显示
select * from emp limit 0,5;  # 第一个参数表示起始位置,第二个参数表示的是条数,不是索引位置
select * from emp limit 5,5;

8.正则

# 在编程中,只要看到reg开头的,基本上都是跟正则相关
select * from emp where name regexp "^j.*(n|y)$";
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!