mysql4表连接_mysql续集4-多表连接

1.多表连接查询

1.1准备表

#建表

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> 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 |

+----+------------+--------+------+--------+

1.2多表连接

1.2.1语法

SELECT 字段列表

FROM 表1 INNER|LEFT|RIGHT JOIN 表2

ON 表1.字段 = 表2.字段;

1.2.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 | 运营 |

+----+------------+--------+------+--------+------+--------------+

24 rows in set (0.00 sec)

mysql>

1.2.3inner join

"取出两张表中共有的部分

employee表中有dep_id=204

department表中有id=203

这两条是非共有数据"

mysql> select * from employee e inner join department 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 | 技术 |

+----+-----------+--------+------+--------+------+--------------+

5 rows in set (0.00 sec)

mysql>

mysql> select * from employee e,department d where e.dep_id=d.id;

1.2.4left join

"以左表为准,左表的数据会全部显示

employee表中dep_id为204的那条,也会存在了"

mysql> select * from employee e left join department 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 |

+----+------------+--------+------+--------+------+--------------+

6 rows in set (0.00 sec)

mysql>

1.2.5right join

"以右表为准,右表中的数据全部显示

department表中id=203那条也会存在"

mysql> select * from employee e right join department 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 | 运营 |

+------+-----------+--------+------+--------+------+--------------+

6 rows in set (0.00 sec)

mysql>

1.2.6全外连接

"显示左右两个表中的全部记录

mysql中不支持全外连接 full join

mysql可以使用下面的方式实现全外连接"

mysql> select * from employee e right join department d on e.dep_id=d.id

-> union

-> select * from employee e left join department 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 | 运营 |

| 6 | jingliyang | female | 18 | 204 | NULL | NULL |

+------+------------+--------+------+--------+------+--------------+

7 rows in set (0.00 sec)

mysql>

"union与union all的区别:union会去掉相同的记录"

mysql> select * from employee e right join department d on e.dep_id=d.id union all select * from employee e left joinn department 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 | 运营 |

| 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 |

+------+------------+--------+------+--------+------+--------------+

12 rows in set (0.00 sec)

mysql>

1.2.7符合条件的连接查询

"#示例1:以内连接的方式查询employee和department表,并且employee表中的age字段值必须大于25,即找出年龄大于25岁的员工以及员工所在的部门"

mysql> select * from employee e right join department d on e.dep_id=d.id where age>25;

+------+---------+--------+------+--------+------+--------------+

| id | name | sex | age | dep_id | id | name |

+------+---------+--------+------+--------+------+--------------+

| 2 | alex | female | 48 | 201 | 201 | 人力资源 |

| 3 | wupeiqi | male | 38 | 201 | 201 | 人力资源 |

| 4 | yuanhao | female | 28 | 202 | 202 | 销售 |

+------+---------+--------+------+--------+------+--------------+

3 rows in set (0.00 sec)

mysql>

"示例2:以内连接的方式查询employee和department表,并且以age字段的升序方式显示"

mysql> select * from employee e right join department d on e.dep_id=d.id where age>25 order by age desc;

+------+---------+--------+------+--------+------+--------------+

| id | name | sex | age | dep_id | id | name |

+------+---------+--------+------+--------+------+--------------+

| 2 | alex | female | 48 | 201 | 201 | 人力资源 |

| 3 | wupeiqi | male | 38 | 201 | 201 | 人力资源 |

| 4 | yuanhao | female | 28 | 202 | 202 | 销售 |

+------+---------+--------+------+--------+------+--------------+

3 rows in set (0.00 sec)

mysql>

2.子查询

#1:子查询是将一个查询语句嵌套在另一个查询语句中。

#2:内层查询语句的查询结果,可以为外层查询语句提供查询条件。

#3:子查询中可以包含:IN、NOT IN、ANY、ALL、EXISTS 和 NOT EXISTS等关键字

#4:还可以包含比较运算符:= 、 !=、> 、

"带in关键字的子查询"

#查询平均年龄在25岁以上的部门名

mysql> select * from department where id in

-> (select dep_id from employee group by dep_id having avg(age)>25);

+------+--------------+

| id | name |

+------+--------------+

| 201 | 人力资源 |

| 202 | 销售 |

+------+--------------+

2 rows in set (0.01 sec)

mysql>

#查看技术部员工姓名

mysql> select * from employee where dep_id =(select id from department where name='技术')

-> ;

+----+-----------+------+------+--------+

| id | name | sex | age | dep_id |

+----+-----------+------+------+--------+

| 1 | egon | male | 18 | 200 |

| 5 | liwenzhou | male | 18 | 200 |

+----+-----------+------+------+--------+

2 rows in set (0.00 sec)

#查看不足1人的部门名

mysql> select name from department where id in( select dep_id from employee group by dep_id having sum(id)<1);

Empty set (0.00 sec)

#查看人数多于1人的部门

mysql> select name from department where id in(

-> select dep_id from employee group by dep_id having sum(id)>1);

+--------------+

| name |

+--------------+

| 技术 |

| 人力资源 |

| 销售 |

+--------------+

3 rows in set (0.00 sec)

mysql>

"带比较运算符的子查询"

#比较运算符:=、!=、>、>=、

#查询大于所有人平均年龄的员工名与年龄

mysql> select name,age from employee where age >

-> (select avg(age) from employee);

+---------+------+

| name | age |

+---------+------+

| alex | 48 |

| wupeiqi | 38 |

+---------+------+

2 rows in set (0.00 sec)

mysql>

#查询大于部门内平均年龄的员工名、年龄

mysql> select * from employee as e inner join(

-> select avg(age) as avg_age,dep_id from employee group by dep_id) as b

-> on e.dep_id=b.dep_id

-> where e.age>b.avg_age;

+----+------+--------+------+--------+---------+--------+

| id | name | sex | age | dep_id | avg_age | dep_id |

+----+------+--------+------+--------+---------+--------+

| 2 | alex | female | 48 | 201 | 43.0000 | 201 |

+----+------+--------+------+--------+---------+--------+

1 row in set (0.00 sec)

mysql>

"带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)

"练习:查询每个部门最新入职的那位员工"

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

);

#插入记录

#三个部门:教学,销售,运营

insert into employee(name,sex,age,hire_date,post,salary,office,depart_id) values

('egon','male',18,'20170301','大使post',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)

;

mysql> select depart_id,max(hire_date) from employee group by depart_id ;

+-----------+----------------+

| depart_id | max(hire_date) |

+-----------+----------------+

| 1 | 2017-03-01 |

| 2 | 2017-01-27 |

| 3 | 2016-03-11 |

+-----------+----------------+

3 rows in set (0.00 sec)

#最终答案

mysql> select * from employee as e inner join (select depart_id,max(hire_date) as max_hidate from employee group by depart_id) as b on e.depart_id=b.depart_id where e.hire_date=b.max_hidate;

+----+--------+--------+-----+------------+------------+--------------+----------+--------+-----------+-----------+------------+

| id | name | sex | age | hire_date | post | post_comment | salary | office | depart_id | depart_id | max_hidate |

+----+--------+--------+-----+------------+------------+--------------+----------+--------+-----------+-----------+------------+

| 1 | egon | male | 18 | 2017-03-01 | 大使post | NULL | 7300.33 | 401 | 1 | 1 | 2017-03-01 |

| 13 | 格格 | female | 28 | 2017-01-27 | sale | NULL | 4000.33 | 402 | 2 | 2 | 2017-01-27 |

| 14 | 张野 | male | 28 | 2016-03-11 | operation | NULL | 10000.13 | 403 | 3 | 3 | 2016-03-11 |

+----+--------+--------+-----+------------+------------+--------------+----------+--------+-----------+-----------+------------+

3 rows in set (0.00 sec)

mysql>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值