MySQL单表查询

sql语句几个关键字的执行顺序:

#书写顺序
select id,name from emp where id > 3;
#执行顺序
from
where
select
"
虽然执行顺序和书写顺序不一致,在写SQL语句的时候可能不知道怎么写,就按照书写顺序的方式写SQL
    select * 先用* 号占位
    之后去补全后面的sql语句
    最后将*号替换成想要的具体字段
"
准备数据:
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 (32) 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 
('jon','male',18,'20170301','sale',17000,401,1),  
('yomy','male',28,'20150302','teacher',20000,401,1),
('kony','male',22,'20140307','teacher',18000,401,1),
('rose','female',81,'20120705','teacher',6300,401,1),
('jessy','female',28,'20110205','teacher',2900,401,1),
('jack','male',45,'20170808','teacher',9000,401,1),
('xiaoming','male',36,'20100905','teacher',10000,401,1),
('duoduo','male',18,'20121205','teacher',8300,401,1),
('duomei','female',51,'20120310','teacher',8800,401,1),
('kankan','male',21,'20180623','teacher',7000,401,1),
('sansan','male',61,'20091214','teacher',1000,401,1),
('momo','male',31,'20190907','teacher',2300,401,1),
('yuming','male',18,'20130806','teacher',3300,401,1),
('keda','female',41,'20160425','teacher',2300,401,1),
('keli','male',35,'20111208','teacher',4300,401,1),
('kemei','female',38,'20190608','teacher',5300,401,1),
('anjing','male',28,'20200305','teacher',6300,401,1),
('anmei','male',20,'20161209','teacher',1300,401,1);
('macky','male',45,'20150908','operation',9000,401,1),
('moming','male',22,'20130307','operation',3600.89,401,1),
('doom','female',61,'20190705','operation',7300.88,401,1),
('meem','female',58,'20110205','operation',8900,401,1),
('qacky','male',35,'20150908','operation',102000,401,1);

#当表字段特别多,展示的时候错乱 可以使用G分行展示;

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=20000 or salary=18000 or salary=17000;
select * from emp where salary in (20000,18000,17000);
#3.查询员工姓名中包含字母o的员工姓名和薪资;
#迷糊查询:
like
    % 匹配任意多个字符
    - 匹配任意单个字符
select name,salary from emp where name like '%o%';
#4.查询员工姓名是由4个字符组成的姓名和薪资  #char_length()
select name,salary from emp where name like '____';
select name,salary from emp where char_length(name)=4;
#5.查询id 小于3或者id大于6的数据;
select * from emp where id not between 3 and 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 is null;

group by 分组

#分组实际应用场景:
    #男女比例
    #部门平均薪资
    #国家之间数据统计
#1.按照部门分组
select * from emp group by post; #报错, 分组之后,最小可操作单位应该是组 不再是组内的单个数据
#分组之后,最小可操作单位应该是组,不再是组内的单个数据
#上述命令在没有设置严格格式的时候是可正常执行的,返回的是分组之后 每个组的第一条数据 但是这不符合分组的规范:分组之后不应该
#考虑单个数据,而应该以组为操作单位(分组之后,没办法直接获取组内单个数据)
#设置严格格式后,分组默认只能拿到分组的数据
select post from emp group by post; 
#按照什么分组就只能拿到分组字段,其他字段不能直接获取 需要借助一些方法
#什么时候需要使用分组?
    #关键字:每个、平均、最高、最低
    #聚合函数:max、min、sum、count、avg、
#1.获取每个部门的最高薪资
select post,max(salary) from emp group by post;
# as 可以给字段起别名,也可以直接省略不写,但是不推荐,不然查找出来的结果容易混乱;
select post as '部门',max(salary) as '薪资' from emp group by post;
#2.获取每个部门的最低薪资
select post,min(salary) from emp group by post;
#3.获取每个部门的平均薪资
select post,avg(salary) from emp group by post;
#4.获取每个部门的薪资总和
select post,sum(salary) from emp group by post;
#5.获取每个部门的人数
select post,count(id) from emp group by post;
select post,count(name) from emp group by post;
select post,count(salary) from emp group by post;
select post,count(age) from emp group by post; null不行
#6.查询分组之后的部门名称和每个部门下所有的员工姓名;
#group_concat 不单单可以支持获取分组之后的其他字段,还支持拼接操作;
select post,group_concat(name) from emp group by post;
select post,group_concat(name,'_well') from emp group by post;
select post,group_concat(name,':',salary) from emp group by post;
#concat 不分组的时候使用
select concat('name:',name),concat('salary:',salary) from emp ;

#补充
#as 语法不单单可以给字段起名,还可以给表起名;
select emp.id,emp.name from emp;
select t1.id,t1.name from emp as t1;
#7. 查询每个人的年薪
select name,salary * 12 from emp; 

分组注意事项

#关键字where 和 group by 同时出现的时候 group by 必须在where的后面
#where 先对整体数据进行过滤之后再分组操作
#where 筛选条件不能使用聚合函数
select id,name,age from emp where max(salary) >3000; #报错
select max(salary) from emp; #不分组,默认整体就是一组
#1.统计各部门年龄在30岁以上的员工平均薪资
    #分步:1 先求出所有年龄大于30岁的员工
         select * from emp where age > 30;
         #2 再对结果进行分组
         select post,avg(salary) from emp where age > 30 group by post;

having分组之后的筛选条件

#having 的语法和where 是一致的,只不过 having 是在分组之后进行的过滤
#having 是可以直接使用聚合函数的
#1.统计各部门年龄在30岁以上的员工平均薪资并且保留平均薪资大于10000的部门;
select post, avg(salary)from emp where age >30 group by post having avg(salary) > 10000;

distinct 去重

#一定要注意,必须是完全一样的数据才可以去重
#一定不要将主键忽视了,有主键存在的情况下是不可能去重的,每个主键不一样,代表每组数据不一样,不是重复的数据
select distinct age from emp;

order by 排序

select * from emp order by salary; #不写asc 默认是升序
select * from emp order by salary asc; #升序
select * from emp order by salary desc; #降序
#先按照age 降序排,如果碰到age相同,则再按照salary升序排;
select * from emp order by age desc,salary asc; 
#1.统计各部门年龄在20岁以上的员工平均工资并且保留平均薪资大于2000的部门,然后对平均工资降序排序;
select post, avg(salary) from emp where age >20 group by post having avg(salary) >2000 order by avg(salary) desc;

limit限制展示条数

#针对数据过多的情况,我们通常都是做分页处理
select * from emp limit 3; #展示3条
select * from emp limit 0,5; #0是起始位置,5是条数
select * from emp limit 5,5;
原文地址:https://www.cnblogs.com/xiehong/p/14722013.html