单表查询
语法:select 字段1,字段2... from 表名
where 条件
group by field
having 筛选
order by field
limit 限制条数
重点:执行优先级:from > where > group by > having > order by > limit
1、利用 from 找到表
2、拿着 where 指定的约束条件,取出表中一条条记录
3、将取出的记录利用 group by 进行分组,如果没有分组,整体作为一个组
4、将分组的结果利用 having 过滤
5、执行 select ,挑选字段
6、去重 distinct
7、将结果按条件排序 order by
8、限制结果的显示条数
创建表:
company.employee
员工id id int
姓名 emp_name varchar
性别 sex enum
年龄 age int
入职日期 hire_date date
岗位 post varchar
职位描述 post_comment varchar
薪水 salary double
办公室 office int
部门编号 depart_id int
#创建表
create table employee(
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
);
#查看表结构
mysql> desc employee;
+--------------+-----------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+-----------------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| 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 | |
+--------------+-----------------------+------+-----+---------+----------------+
#插入记录
#三个部门:教学,销售,运营
insert into employee(name,sex,age,hire_date,post,salary,office,depart_id) values
('egon','male',18,'20170301','老男孩驻沙河办事处外交大使',7300.33,401,1), #以下是教学部
('alex','male',78,'20150302','teacher',1000000.31,401,1),
('wupeiqi','male',81,'20130305','teacher',8300,401,1),
('yuanhao','male',73,'20140701','teacher',3500,401,1),
('liwenzhou','male',28,'20121101','teacher',2100,401,1),
('jingliyang','female',18,'20110211','teacher',9000,401,1),
('jinxin','male',18,'19000301','teacher',30000,401,1),
('成龙','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)
;
from:确定要用哪个表
简单查询:
select * from employee;
select name, age from employee;
# 避免重复 distinct
select distinct(post) from employee;
#通过四则运算查询
select name, salary as 一年平均工资 from employee;
select name, salary 一年平均工资 from employee;
+------------+--------------------+
| name | 一年平均工资 |
+------------+--------------------+
| egon | 7300.33 |
| alex | 1000000.31 |
| wupeiqi | 8300.00 |
| yuanhao | 3500.00 |
+------------+--------------------+
18 rows in set (0.00 sec)
定义显示格式:
concat() 函数用于连接字符串
mysql> select concat('姓名:',name,'年薪:',salary*12) as Annual_salary from employee;
+-------------------------------------+
| Annual_salary |
+-------------------------------------+
| 姓名:wupeiqi年薪:99600.00 |
| 姓名:yuanhao年薪:42000.00 |
......
+-------------------------------------+
concat_ws('分隔符',字段1,字段2)
mysql> select concat_ws('|',name,salary*12) as annual_salary from employee;
+----------------------+
| annual_salary |
+----------------------+
| liwenzhou|25200.00 |
| jingliyang|108000.00 |
小练习:
1 查出所有员工的名字,薪资,格式为
<名字:egon> <薪资:3000>
2 查出所有的岗位(去掉重复)
3 查出所有员工名字,以及他们的年薪,年薪的字段名为annual_year
1、select concat('<名字:',name,'><薪资:',salary,'>') from employee;
2、select distinct(post) as 岗位 from employee;
select distinct post from employee;
3、select name, salary*12 as annual_year from employee;
where:条件判断,筛选数据
对整体数据做筛选。
可以使用的条件判断:
1、< > <= >= != <>
2、between 10 and 20 相当于: x >= 10 and x <= 20
3、in(10, 20, 30) 值是10或20或30
4、like 'egon%'
%:表示任意字符
_:表示匹配单个字符
5、逻辑运算符:and or not
# 单条件查询
select * from employee where post = 'sale';
# 多条件查询
select * from employee where post = 'sale' and salary > 3000;
# 关键字 between and
select name, salary from employee where salary between 1000 and 2000;
select name, salary from employee where salary not between 1000 and 2000;
# 关键字 is null, is not null:
# 判断某一个字段为null不能用=
select name, salary from employee where post_comment is null;
select name, salary from employee where post_comment is not null;
# 关键字 in,not in 集合查询
select name, salary from employee where salary in (2100, 3000, 2000);
# 模糊匹配查询
# % 匹配任意字符
# _ 匹配单个字符
select name,salary from employee where name like 'j%';
+------------+----------+
| name | salary |
+------------+----------+
| jingliyang | 9000.00 |
| jinxin | 30000.00 |
+------------+----------+
select name,salary from employee where name like '____';
+------+------------+
| name | salary |
+------+------------+
| egon | 7300.33 |
| alex | 1000000.31 |
+------+------------+
小练习
1. 查看岗位是teacher的员工姓名、年龄
2. 查看岗位是teacher且年龄大于30岁的员工姓名、年龄
3. 查看岗位是teacher且薪资在9000-1000范围内的员工姓名、年龄、薪资
4. 查看岗位描述不为NULL的员工信息
5. 查看岗位是teacher且薪资是10000或9000或30000的员工姓名、年龄、薪资
6. 查看岗位是teacher且薪资不是10000或9000或30000的员工姓名、年龄、薪资
7. 查看岗位是teacher且名字是jin开头的员工姓名、年薪
1、select name, age from employee where post = 'teacher';
2、select name, age from employee where post = 'teacher' and age > 30;
3、select name, age, salary from employee where post = 'teacher' and salary between 1000 and 9000;
4、select * from employee where post_comment is not null;
5、select name, age, salary from employee where post = 'teacher' and salary in (10000, 9000, 30000);
6、select name, age, salary from employee where post = 'teacher' and salary not in (10000, 9000, 30000);
7、select name, salary from employee where post = 'teacher' and name like 'jin%';
group by:分组
多条记录之间的某个字段值相同,该字段通常用来作为分组的依据
什么是分组?
- 明确一点:分组发生在where之后,操作的是where条件判断后的记录
- 分组是将所有记录按照某个相同字段值进行分类,比如根据性别分男、女两个组
为什么要分组
- 取性别男的人数、性别女的人数
- 取每个部门的员工数
大前提
MySQL分组之后,只能获取分组的字段信息,无法拿到其他字段信息,但是这时候,可以通过聚合函数查看组内信息。
比如:select * from employee group by post,你只能拿到 post 字段的信息。
selecet * from employee group by post;
# 报错,分组只能查看分组字段,和聚合函数。
mysql> select post from employee group by post;
+-----------------------------------------+
| post |
+-----------------------------------------+
| operation |
| sale |
| teacher |
+-----------------------------------------+
mysql> select post,count(id) from employee group by post;
+-----------------------------------------+-----------+
| post | count(id) |
+-----------------------------------------+-----------+
| operation | 5 |
| sale | 5 |
| teacher | 7 |
| 老男孩驻沙河办事处外交大使 | 1 |
+-----------------------------------------+-----------+
4 rows in set (0.00 sec)
MySQL中分组之后 只能拿到分组的字段信息 无法直接获取其他字段信息
但是你可以通过其他方法(聚合函数)简介的获取
如果你的MySQL不报错 说明严格模式没有设置
show variables like '%mode%';
set session 当前窗口有效
set global 全局有效
set global sql_mode="strict_trans_tables,only_full_group_by";
select * from emp group by post;
group by
-
单独使用 group by 分组
group by 按照post分组,那么 select 查询的字段只能是post字段,要想获取组内其他信息,需要用到函数。
-
group by 和 group_concat 函数一起用
# 按照岗位分组,并查看组内所有成员名 # 和group_concat连用,可以查看组内的所有字段的值,可以查看多个字段的值。 # group_concat()能够拿到分组后每一个数据指定字段(可以是多个)对应的值 mysql> select post, group_concat(name) from employee group by post; +-----------------------------------------+---------------------------------------------------------+ | post | group_concat(name) | +-----------------------------------------+---------------------------------------------------------+ | operation | 张野,程咬金,程咬银,程咬铜,程咬铁 | | sale | 歪歪,丫丫,丁丁,星星,格格 | | teacher | alex,wupeiqi,yuanhao,liwenzhou,jingliyang,jinxin,成龙 | | 老男孩驻沙河办事处外交大使 | egon | +-----------------------------------------+---------------------------------------------------------+ mysql> select post, group_concat(sex,'|',id) from employee group by post; +-----------------------------------------+----------------------------------------------------+ | post | group_concat(sex,'|',id) | +-----------------------------------------+----------------------------------------------------+ | operation | male|14,male|15,female|16,male|17,female|18 | | sale | female|9,female|10,female|11,female|12,female|13 | | teacher | male|2,male|3,male|4,male|5,female|6,male|7,male|8 | | 老男孩驻沙河办事处外交大使 | male|1 | +-----------------------------------------+----------------------------------------------------+ 4 rows in set (0.00 sec)
group_concat 和 concat:
concat就是用来帮你拼接数据,concat 不分组情况下使用
group_concat 分组之后使用,也可以拼接数据。 -
group by 和 聚合函数一起用
# 按post分组,并查看组内人数 select post count(id) from employee group by post;
-
强调:
如果我们用unique唯一的字段作为分组的依据,则每一条记录自成一组,这种分组没有意义 多条记录之间的某个字段值相同,该字段通常用来作为分组的依据
四 聚合函数
# 强调:聚合函数聚合的是组的内容,若是没有分组,则默认一组
# 在统计分组内个数的时候 填写任意非空字段都可以完成计数,推荐使用能够唯一标识数据的字段,比如id字段
示例:
SELECT COUNT(*) FROM employee;
SELECT COUNT(*) FROM employee WHERE depart_id=1;
SELECT MAX(salary) FROM employee;
SELECT MIN(salary) FROM employee;
SELECT AVG(salary) FROM employee;
SELECT SUM(salary) FROM employee;
SELECT SUM(salary) FROM employee WHERE depart_id=3;
ONLY_FULL_GROUP_BY
#查看MySQL 5.7默认的sql_mode如下:
mysql> select @@global.sql_mode;
ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
#!!!注意
ONLY_FULL_GROUP_BY的语义就是确定select target list中的所有列的值都是明确语义,简单的说来,在ONLY_FULL_GROUP_BY模式下,target list中的值要么是来自于聚集函数的结果,要么是来自于group by list中的表达式的值。
#设置sql_mole如下操作(我们可以去掉ONLY_FULL_GROUP_BY模式):
mysql> set global sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';
mysql> select @@global.sql_mode;
+-------------------+
| @@global.sql_mode |
+-------------------+
| |
+-------------------+
1 row in set (0.00 sec)
mysql> select * from emp group by post;
+----+------+--------+-----+------------+----------------------------+--------------+------------+--------+-----------+
| id | name | sex | age | hire_date | post | post_comment | salary | office | depart_id |
+----+------+--------+-----+------------+----------------------------+--------------+------------+--------+-----------+
| 14 | 张野 | male | 28 | 2016-03-11 | operation | NULL | 10000.13 | 403 | 3 |
| 9 | 歪歪 | female | 48 | 2015-03-11 | sale | NULL | 3000.13 | 402 | 2 |
| 2 | alex | male | 78 | 2015-03-02 | teacher | NULL | 1000000.31 | 401 | 1 |
| 1 | egon | male | 18 | 2017-03-01 | 老男孩驻沙河办事处外交大使 | NULL | 7300.33 | 401 | 1 |
+----+------+--------+-----+------------+----------------------------+--------------+------------+--------+-----------+
4 rows in set (0.00 sec)
#由于没有设置ONLY_FULL_GROUP_BY,于是也可以有结果,默认都是组内的第一条记录,但其实这是没有意义的
mysql> set global sql_mode='ONLY_FULL_GROUP_BY';
Query OK, 0 rows affected (0.00 sec)
mysql> quit #设置成功后,一定要退出,然后重新登录方可生效
Bye
mysql> use db1;
Database changed
mysql> select * from emp group by post; #报错
ERROR 1055 (42000): 'db1.emp.id' isn't in GROUP BY
mysql> select post,count(id) from emp group by post; #只能查看分组依据和使用聚合函数
+----------------------------+-----------+
| post | count(id) |
+----------------------------+-----------+
| operation | 5 |
| sale | 5 |
| teacher | 7 |
| 老男孩驻沙河办事处外交大使 | 1 |
+----------------------------+-----------+
4 rows in set (0.00 sec)
小练习
1. 查询岗位名以及岗位包含的所有员工名字
2. 查询岗位名以及各岗位内包含的员工个数
3. 查询公司内男员工和女员工的个数
4. 查询岗位名以及各岗位的平均薪资
5. 查询岗位名以及各岗位的最高薪资
6. 查询岗位名以及各岗位的最低薪资
7. 查询男员工与男员工的平均薪资,女员工与女员工的平均薪资
1、select post, group_concat(name) from employee group by post;
2、select post, count(id) from employee group by post;
3、select sex, count(id) from employee group by sex;
4、select post, avg(salary) from employee group by post;
5、select post, max(salary) from employee group by post;
6、select post, min(salary) from employee group by post;
7、select sex, avg(salary) from employee group by sex;
having:筛选数据
对分组之后的数据再次筛选。
having 与 where:
执行优先级:where > group by > having
1、 where 发生在分组 group by 之前,因此 where 可以有任意字段,但是不能使用聚合。
2、 having 发生在分组 group by 之后,只能使用分组的字段,但是可以使用聚合来使用其他字段。
select post, group_concat(id) from employee group by post having salary > 10000;
ERROR 1054 (42S22): Unknown column 'salary' in 'having clause'
having 只能使用分组 group by 之后的字段。
select post, group_concat(name),avg(salary) from employee group by post having avg(salary) > 10000;
小练习
1. 查询各岗位内包含的员工个数小于2的岗位名、岗位内包含员工名字、个数
2. 查询各岗位平均薪资大于10000的岗位名、平均工资
3. 查询各岗位平均薪资大于10000且小于20000的岗位名、平均工资
1、select post, group_concat(name), count(id) from employee group by post having count(id) < 5;
2、select post,avg(salary) from employee group by post having avg(salary) > 10000
3、select post, avg(salary) from employee group by post having avg(salary) between 10000 and 20000;
distinct:去重
对重复的数据进行一个去重,去重必须数据是一模一样的才能去重,只要有一个不一样 都不能算是的重复的数据。
order by:排序
介绍:
默认是升序 asc,也可以变成降序 desc。
按单列排序
select * from employee order by salary desc; #降序
select * from employee order by salary asc; # 升序
按多列排序
select * from employee order by age, salary; # 先按照age做升序 age相同的情况下再按照salary做升序
select * from emp order by age asc,salary desc; # 先按照age做升序,age相同,再按salary做降序。
limit:限制查询记录数
limit 5:默认位置是0
limit 0, 5 : 从位置0开始,取五条记录结束
limit 5, 5: 从位置5开始,取五条。
mysql> select name,salary from employee order by salary desc limit 5, 5;
+-----------+------------+
| name | salary |
+-----------+------------+
| alex | 1000000.31 |
| jinxin | 30000.00 |
| 程咬金 | 20000.00 |
| 程咬银 | 19000.00 |
| 程咬铜 | 18000.00 |
+-----------+------------+
使用正则查询
+------+------------+
| name | salary |
+------+------------+
| alex | 1000000.31 |
+------+------------+
小结:对字符串匹配方式
WHERE name = 'egon'; #直接匹配
WHERE name LIKE 'yua%'; # 模糊匹配
WHERE name REGEXP 'on$'; # 正则匹配
多表查询
表数据准备:
#建表
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,
dep_id int
);
#插入数据
insert into department values
(200,'技术'),
(201,'人力资源'),
(202,'销售'),
(203,'运营');
insert into employee(name,sex,age,dep_id) values
('egon','male',18,200),
('alex','female',48,201),
('wupeiqi','male',38,201),
('yuanhao','female',28,202),
('liwenzhou','male',18,200),
('jingliyang','female',18,204)
;
#查看表结构和数据
mysql> desc department;
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id | int(11) | YES | | NULL | |
| name | varchar(20) | YES | | NULL | |
+-------+-------------+------+-----+---------+-------+
mysql> desc employee;
+--------+-----------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------+-----------------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(20) | YES | | NULL | |
| sex | enum('male','female') | NO | | male | |
| age | int(11) | YES | | NULL | |
| dep_id | int(11) | YES | | NULL | |
+--------+-----------------------+------+-----+---------+----------------+
mysql> select * from department;
+------+--------------+
| id | name |
+------+--------------+
| 200 | 技术 |
| 201 | 人力资源 |
| 202 | 销售 |
| 203 | 运营 |
+------+--------------+
mysql> select * from employee;
+----+------------+--------+------+--------+
| id | name | sex | age | dep_id |
+----+------------+--------+------+--------+
| 1 | egon | male | 18 | 200 |
| 2 | alex | female | 48 | 201 |
| 3 | wupeiqi | male | 38 | 201 |
| 4 | yuanhao | female | 28 | 202 |
| 5 | liwenzhou | male | 18 | 200 |
| 6 | jingliyang | female | 18 | 204 |
+----+------------+--------+------+--------+
多表连接查询
SELECT 字段列表
FROM 表1 INNER|LEFT|RIGHT JOIN 表2
ON 表1.字段 = 表2.字段;
交叉连接:
不适用任何匹配条件,生成笛卡尔积
mysql> select * from employee,department;
+----+------------+--------+------+--------+------+--------------+
| id | name | sex | age | dep_id | id | name |
+----+------------+--------+------+--------+------+--------------+
| 1 | egon | male | 18 | 200 | 200 | 技术 |
| 1 | egon | male | 18 | 200 | 201 | 人力资源 |
| 1 | egon | male | 18 | 200 | 202 | 销售 |
| 1 | egon | male | 18 | 200 | 203 | 运营 |
| 2 | alex | female | 48 | 201 | 200 | 技术 |
| 2 | alex | female | 48 | 201 | 201 | 人力资源 |
| 2 | alex | female | 48 | 201 | 202 | 销售 |
| 2 | alex | female | 48 | 201 | 203 | 运营 |
| 3 | wupeiqi | male | 38 | 201 | 200 | 技术 |
| 3 | wupeiqi | male | 38 | 201 | 201 | 人力资源 |
| 3 | wupeiqi | male | 38 | 201 | 202 | 销售 |
| 3 | wupeiqi | male | 38 | 201 | 203 | 运营 |
| 4 | yuanhao | female | 28 | 202 | 200 | 技术 |
| 4 | yuanhao | female | 28 | 202 | 201 | 人力资源 |
| 4 | yuanhao | female | 28 | 202 | 202 | 销售 |
| 4 | yuanhao | female | 28 | 202 | 203 | 运营 |
| 5 | liwenzhou | male | 18 | 200 | 200 | 技术 |
| 5 | liwenzhou | male | 18 | 200 | 201 | 人力资源 |
| 5 | liwenzhou | male | 18 | 200 | 202 | 销售 |
| 5 | liwenzhou | male | 18 | 200 | 203 | 运营 |
| 6 | jingliyang | female | 18 | 204 | 200 | 技术 |
| 6 | jingliyang | female | 18 | 204 | 201 | 人力资源 |
| 6 | jingliyang | female | 18 | 204 | 202 | 销售 |
| 6 | jingliyang | female | 18 | 204 | 203 | 运营 |
+----+------------+--------+------+--------+------+--------------+
内连接:
只连接匹配的行,找两张表共有部分,相当于从笛卡尔积结果中筛选出了正确的结果。
只取两张表有对应关系的记录。
mysql> select e.name, e.age, e.dep_id, d.id, d.name from employee as e inner join department as d on e.dep_id = d.id;
+-----------+------+--------+------+--------------+
| name | age | dep_id | id | name |
+-----------+------+--------+------+--------------+
| egon | 18 | 200 | 200 | 技术 |
| alex | 48 | 201 | 201 | 人力资源 |
| wupeiqi | 38 | 201 | 201 | 人力资源 |
| yuanhao | 28 | 202 | 202 | 销售 |
| liwenzhou | 18 | 200 | 200 | 技术 |
+-----------+------+--------+------+--------------+
左连接:
在内连接的基础上,保留左表不对应的记录。
mysql> select * from employee as e left join department as d on e.dep_id = d.id;
+----+------------+--------+------+--------+------+--------------+
| id | name | sex | age | dep_id | id | name |
+----+------------+--------+------+--------+------+--------------+
| 1 | egon | male | 18 | 200 | 200 | 技术 |
| 5 | liwenzhou | male | 18 | 200 | 200 | 技术 |
| 2 | alex | female | 48 | 201 | 201 | 人力资源 |
| 3 | wupeiqi | male | 38 | 201 | 201 | 人力资源 |
| 4 | yuanhao | female | 28 | 202 | 202 | 销售 |
| 6 | jingliyang | female | 18 | 204 | NULL | NULL |
+----+------------+--------+------+--------+------+--------------+
右连接:
在内连接的基础上,保留右表不对应的记录。
mysql> select * from employee as e right join department as d on e.dep_id = d.id;
+------+-----------+--------+------+--------+------+--------------+
| id | name | sex | age | dep_id | id | name |
+------+-----------+--------+------+--------+------+--------------+
| 1 | egon | male | 18 | 200 | 200 | 技术 |
| 2 | alex | female | 48 | 201 | 201 | 人力资源 |
| 3 | wupeiqi | male | 38 | 201 | 201 | 人力资源 |
| 4 | yuanhao | female | 28 | 202 | 202 | 销售 |
| 5 | liwenzhou | male | 18 | 200 | 200 | 技术 |
| NULL | NULL | NULL | NULL | NULL | 203 | 运营 |
+------+-----------+--------+------+--------+------+--------------+
全连接:
在内连接的基础上保留左、右表没有对应关系的的记录
mysql> select * from employee as e left join department as d on e.dep_id = d.id
-> union
-> select * from employee as e right join department as d on e.dep_id = d.id;
+------+------------+--------+------+--------+------+--------------+
| id | name | sex | age | dep_id | id | name |
+------+------------+--------+------+--------+------+--------------+
| 1 | egon | male | 18 | 200 | 200 | 技术 |
| 5 | liwenzhou | male | 18 | 200 | 200 | 技术 |
| 2 | alex | female | 48 | 201 | 201 | 人力资源 |
| 3 | wupeiqi | male | 38 | 201 | 201 | 人力资源 |
| 4 | yuanhao | female | 28 | 202 | 202 | 销售 |
| 6 | jingliyang | female | 18 | 204 | NULL | NULL |
| NULL | NULL | NULL | NULL | NULL | 203 | 运营 |
+------+------------+--------+------+--------+------+--------------+
符合条件连接查询
#示例1:以内连接的方式查询employee和department表,并且employee表中的age字段值必须大于25,即找出年龄大于25岁的员工以及员工所在的部门
#示例2:以内连接的方式查询employee和department表,并且以age字段的升序方式显示
1、select * from employee as e inner join department as d on e.dep_id = d.id where e.age > 25;
2、select * from employee as e inner join department as d on e.dep_id = d.id order by age asc;
子查询
就是将一个查询语句的结果用括号括起来当作另外一个查询语句的条件去用
带IN关键字的子查询
# 查询平均年龄在25岁以上的部门名
select name from department where id in (select dep_id from employee group by dep_id having avg(age) > 25);
# 查看技术部员工姓名
select name from employee where dep_id in (select id from department where name = '技术');
# 查看不足1人的部门名(子查询得到的是有人的部门id)
select name from department where id not in (select distinct dep_id from employee);
带比较运算符的子查询
#比较运算符:=、!=、>、>=、<、<=、<>
#查询大于所有人平均年龄的员工名与年龄
mysql> select name,age from emp where age > (select avg(age) from emp);
+---------+------+
| name | age |
+---------+------+
| alex | 48 |
| wupeiqi | 38 |
+---------+------+
2 rows in set (0.00 sec)
#查询大于部门内平均年龄的员工名、年龄
select t1.name,t1.age from emp t1
inner join
(select dep_id,avg(age) avg_age from emp group by dep_id) t2
on t1.dep_id = t2.dep_id
where t1.age > t2.avg_age;
带exist关键字的子查询
EXISTS关字键字表示存在。在使用EXISTS关键字时,内层查询语句不返回查询的记录。
而是返回一个真假值。True或False
当返回True时,外层查询语句将进行查询;当返回值为False时,外层查询语句不进行查询
#department表中存在dept_id=203,Ture
mysql> select * from employee
-> where exists
-> (select id from department where id=200);
+----+------------+--------+------+--------+
| id | name | sex | age | dep_id |
+----+------------+--------+------+--------+
| 1 | egon | male | 18 | 200 |
| 2 | alex | female | 48 | 201 |
| 3 | wupeiqi | male | 38 | 201 |
| 4 | yuanhao | female | 28 | 202 |
| 5 | liwenzhou | male | 18 | 200 |
| 6 | jingliyang | female | 18 | 204 |
+----+------------+--------+------+--------+
#department表中存在dept_id=205,False
mysql> select * from employee
-> where exists
-> (select id from department where id=204);
Empty set (0.00 sec)