单表查询
-
sql查询语句的完整语法
select .. from .. where .. group by .. having .. order by .. limit ..
-
where条件的使用
-
功能:对表中的数据进行筛选和过滤
-
语法:
1.判断的符号: = > >= < <= != <>不等于 2.拼接条件的关键字 and or not 3.查询的区间范围值 between between 小值 and 大值 [小值,大值] 查询两者之间这个范围内所有值 4.查询具体某个值的范围 in in(1,2,3)指定的范围 5.模糊查询like ‘%‘ 通配符 like ‘%a‘ 匹配以a结尾的任意长度的字符串 like ‘a%‘ 匹配以a开头的任意长度的字符串 like ‘%a%‘ 匹配含有a字母的任意长度的字符串 like ‘_a‘ 个数一共是2个字符,必须以a结尾,前面的字符随意 like ‘a__‘ 个数一共是3个字符,必须以a开头,后面的字符随意
-
查询练习
create database db0618; use db0618; create table employee( id int not null unique auto_increment, emp_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 ); mysql> desc employee; +--------------+-----------------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +--------------+-----------------------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | emp_name | varchar(20) | NO | | NULL | | | sex | enum(‘male‘,‘female‘) | NO | | male | | | age | int(3) unsigned | NO | | 28 | | | hire_date | date | NO | | NULL | | | post | varchar(50) | YES | | NULL | | | post_comment | varchar(100) | YES | | NULL | | | salary | double(15,2) | YES | | NULL | | | office | int(11) | YES | | NULL | | | depart_id | int(11) | YES | | NULL | | +--------------+-----------------------+------+-----+---------+----------------+ 10 rows in set (0.00 sec) ###单条件查询 #查询部门是sale的所有员工姓名; select emp_name from employee where post = ‘sale‘; ###多条件的查询 #部门是teacher,收入大于10000的所有数据 select * from employee where post=‘teacher‘ and salary>10000; ###关键字between .. and.. #收入在1万到2万之间的所有员工姓名和收入 select emp_name,salary from employee where salary between 10000 and 20000; #收入不在1万到2万之间的所有员工姓名和收入 select emp_name,salary from employee where salary not between 10000 and 20000; ### null 关键字 在查询的时候,要用is进行判定,不要用= #查询post_comment是空的所有数据 select * from employee where post_comment is null; #查询post_comment不是空的所有数据 select * from employee where post_comment is not null; #查询空值 update employee set post_comment = ‘‘ where id = 1; select * from employee where post_comment = ‘‘; # 关键字 in 在..之中 查询 #查询收入是3000,4000,5000,8000所有员工的姓名和收入 select emp_name,salary from employee where salary=3000 or salary=4000 or salary=5000 or salary=8000 #用in优化,在小括号里面具体指定某个值 select emp_name,salary from employee where salary in(3000,4000,5000,8000); #不在 not in .. select emp_name,salary from employee where salary not in(3000,4000,5000,8000); #模糊查询like ‘%‘ ‘_‘通配符 # ‘%‘通配符 以on结尾的员工姓名 select emp_name,age,post from employee where emp_name like ‘%on‘ # ‘_‘ 通配符可以限定具体的长度 select emp_name,age,post from employee where emp_name like ‘a_e_‘ #concat 拼接 (as 起别名) select concat(‘姓名:‘,emp_name,‘工资:‘,salary) from employee; select concat(‘姓名:‘,emp_name,‘工资:‘,salary) as aa from employee; #concat_ws(拼接的符号,参数1,参数2,参数3...) select concat_ws(‘:‘,emp_name,salary) from employee #计算年薪 可以在mysql中使用四则运算(+ - * /) select concat_ws(‘:‘,emp_name,salary*12) as cc from employee;
-
group by子句 分组分类
-
group by 字段 对数据进行分类,by后面接什么字段,select就搜索什么字段
#按照性别进行分类 select sex from employee group by sex; #按照部门进行分类 select post from employee group by post;
-
group_concat 按照分类的形式进行字段的拼接
select group_concat(emp_name),post from employee group by post;
-
聚合函数
#count 统计总数 *所有 select count(*) from employee; #max 统计最大值 select max(salary) from employee; #min 统计最小值 select min(salary) from employee; #avg 统计平均值 select avg(salary) from employee; #sum 统计总和 select sum(salary) from employee;
-
一般情况 分组 + 聚合函数 配合使用
#查询部门名以及各部门的平均薪资 select post,avg(salary) from employee group by post; #查询部门名以及各部门的最高薪资 select post,max(salary) from employee group by post; #查询部门名以及各部门的最低薪资 select post,min(salary) from employee group by post; #查询公司内男员工和女员工的个数 select sex,count(*) from employee group by sex; #查询部门名以及部门包含的所有员工名字 select group_concat(emp_name) from employee group by post #可以group by两个字段,即可搜索两个字段 select emp_name,post from employee group by post,emp_name;
-
-
having 数据在分类分组之后,进行二次数据过滤,一般是配合group by 使用,分组之后再过滤
#找出各部门平均薪资,并且大于10000以上的所有部门 select post,avg(salary) from employee group by post having avg(salary)>10000; #查询各岗位内包含的员工个数小于2的岗位名、查询岗位内包含员工名字、个数 select post,group_concat(emp_name),count(*) group by post having count(*) <2 #查询各岗位平均薪资小于10000的岗位名、平均工资 select post,avg(salary) from employee group by post having avg(salary) < 10000 #查询各岗位平均薪资大于10000且小于20000的岗位名、平均工资 select post,avg(salary) from employee group by post having avg(salary) between 10000 and 20000; #between 10000 and 20000 这两个值可以取到 select post,avg(salary) from employee group by post having avg(salary)>10000 and avg(salary)<20000;
-
order by排序 ,按照什么字段进行排序
- asc 升序:从小到大(默认)
- desc 降序:从大到小
select * from employee order by age #(asc 默认升序) select * from employee order by age desc #(desc 降序) #查询所有员工信息,先按照age升序排序,如果age相同则按照hire_date降序排序 select emp_name,age,hire_date,post from employee order by age,hire_date desc; #查询各岗位平均薪资大于10000的岗位名、平均工资,结果按平均薪资升序排列 select post,avg(salary) from employee group by post having avg(salary)>10000 order by avg(salary) #查询各岗位平均薪资大于10000的岗位名、平均工资,结果按平均薪资降序排列 select post,avg(salary) from employee group by post having avg(salary)>10000 order by avg(salary) desc;
-
limit 限制查询条数(数据分页)
- limit m,n m代表从第几条数据查询,n代表查询几条,m=0代表的是第一条
select * from employee limit 0,5 从第一条数据开始搜,搜5条 select * from employee limit 5,5 从第六条数据开始搜,搜5条 #只查询一条数据 select * from employee limit 1 #找数据库当中最后一条数据 select * from employee order by id limit 1 #找数据库当中最后三条数据 select * from employee order by id limit 3
-
使用正则表达式查询数据(不推荐使用,效率不高)
select * from employee where emp_name regexp ‘.*on$‘; #.*? 问号?不识别 select * from employee where emp_name regexp ‘^程‘; select * from employee where emp_name regexp ‘^程.*金‘;
-
多表查询
-
练习
#建表 create table department( id int, name varchar(20) ); create table employee( id int primary key auto_increment, name varchar(20), sex enum(‘male‘,‘female‘) not null default ‘male‘, age int, de_id int );
-
内连接:(内联查询 inner join)-> 查询两表或者多表满足条件的所有数据被查询出来(两表之间共有的部分)
#两表查询 #select 字段 from 表1 inner join 表2 on 必要的关联条件 #多表查询 #select 字段 from 表1 inner join 表2 on 必要的关联条件1 inner join 表3 on 必要的关联条件2... #基本语法 inner join on .. on后面接必要的关联条件 select * from employee inner join department on employee.dep_id = department.id; #用as 起别名(推荐) select * from employee as e inner join department as d on e.dep_id = d.id; # as 可以省略掉 select * from employee e inner join department d on e.dep_id = d.id; #where默认实现的就是内联查询的效果 select * from employee,departmet where employee.dep_id = department.id; select * from employee as e,department as d where d.dep_id = d.id;
-
外连接
-
左连接(左联查询 left join)以左表为主,右表为辅,完整查询左表所有数据,右表没有的数据补null
select * from employee left join department on employee.dep_id = department.id;
-
右连接(右联查询 right join)以右表为主,左表为辅,完整查询右表所有数据,左表没有的数据补null
select * from employee right join department on employee.dep_id = department.id;
-
全连接(全连接 union)所有的数据都合并起来
select * from employee left join department on employee.dep_id = department.id union select * from employee right join department on employee.dep_id = department.id;
-
子查询
- 子查询:嵌套查询
- sql语句当中又嵌套了另外一条sql语句,用括号()抱起来,表达一个整体
- 一般应用在from子句后面表达一张表 where子句后面表达一个条件
- 查询速度从快到慢:单表查询 -> 联表查询 ->子查询
#找出平均年龄大于25岁以上的部门
1.普通where写法
select
d.id,d.name
from
employee as e,department as d
where
e.dep_id = d.id
group by
d.id,d.name
having
avg(e.age)>25;
2. inner join
select
d.id,d.name
from
employee as e inner join department as d on e.dep_id=d.id
group by
d.id,d.name
having
avg(e.age)>25;
3.子查询
(1)先找出平均年龄大于25岁的部门id
select dep_id from employee group by dep_id having avg(age)>25;
(2)通过部门id,找部门名字
select name from department where id in(201,202);
(3)综合拼接
select name from department where id in(select dep_id from employee group by dep_id having avg(age)>25);
#查看技术部门员工姓名
1.普通where查询
select
e.name
from
department as d,employee as e
where
d.id = e.dep_id
and
d.name = ‘技术‘;
2.inner join写法
select
e.name
from
department as inner join demployee as e on d.id = e.dep_id
where
d.name = ‘技术‘;
3.子查询写法
(1)找技术部门对应id
select id from department where name = ‘技术‘;
(2)通过id找员工姓名
select name from employee where dep_id = 200;
(3)综合拼接
select name from employee where dep_id = (select id from department where name = ‘技术‘);
#查看那个部门没员工
(1)联表写法(把null的数据露出来,员工的部门dep_id 为null,代表这个部门没人)
select
d.id,d.name
from
department as d,employee as e on d.id = e.dep_id
where
e.dep_id is null
(2)子查询
1.先查询,员工在那些部门(所有员工的分类分别是200 201 202 204)
select dep_id from employee group by dep_id;
2.把不在部门的数据找出来
select from department where id not in (200,201,202,204);
3.联合拼接
select from department where id not in (select dep_id from employee group by dep_id)
#查询大于平均年龄的员工名与年龄
1.假设平均年龄是20岁
select name,age from employee where age >20
2.找平均年龄
select avg(age) from employee;
3.综合拼装
select name,age from employee where age >(select avg(age) from employee);
#把大于其本部门平均年龄的员工名和姓名查出来
1.先计算各部门平均年龄是多少
select dep_id,avg(age) from employee group by dep_id;
2.把查询的各部门的平均年龄和过去的employee联表,变成一张更大的表,方便做一次单表查询
select
*
from
employee as t1 inner join (1号查询到的数据) as t2 on t1.dep_id = t2.dep_id
3.综合拼接
select
*
from
employee as t1 inner join (select dep_id,avg(age) as avg_age from employee group by dep_id) as t2 on t1.dep_id = t2.dep_id
4.做最后的数据筛选 age > 平均年龄
select
*
from
employee as t1 inner join (select dep_id,avg(age) as avg_age from employee group by dep_id) as t2 on t1.dep_id = t2.dep_id
where
t1.age>t2.avg_age
#查询每个部门最新入职的那位员工 #利用上一套数据表进行查询;
1.找每个部门最大的入职时间
select post,max(hire_date) as max_date from employee group by post
2.把子查询搜出来的数据和employee联合成一张更大的表,做一次单表查询
select
t1.emp_name,t1.hire_date
from
employee as t1 inner join(1号查出来的数据) as t2 on t1.post = t2.post
where
t1.hire_date = t2.max_date
3.综合拼接
select
t1.emp_name,t1.hire_date
from
employee as t1 inner join(select post,max(hire_date) as max_date from employee group by post) as t2 on t1.post = t2.post
where
t1.hire_date = t2.max_date
#带EXISTS关键字的子查询
#exists 关键字,表达存在;
#如果内层sql能够查到数据,返回True,外层sql执行查询语句
#如果内层sql能够查到数据,返回False,外层sql不执行查询语句
select * from employee where exists (select * from employee where id = 1)
- 子查询总结:
- 子查询可以单独作为一个临时数据,临时的表,临时的字段
- 一般用在from where select 子句后面
- 用法在于可以通过查询出来的临时数据和另外的表联合,变成一张更大的表,在做单表查询查到想要的数据