- 什么是表连接:同时对多张表进行查询操作,表与表之间要通过连接条件来连接。一般这个连接条件是主键列是否等于外键列。表连接的主要三种方式是:
连接方式 | 概念说明 |
---|---|
内连接 | 分为显示内连接和隐式内连接,查询的数据必须左右两表都存在才会显示 |
左连接 | 又叫左外连接,查询的数据以左表为准,即使左表中的数据在其他表中没有匹配也会查询出来,且会以null补齐 |
右连接 | 又叫右外连接,和左外连接相反,查询的数据以右表为准,即使右表中的数据在其他表中没有匹配也会查询出来,且会以null补齐 |
数据准备:
#创建一个数据库company
CREATE DATABASE IF NOT EXISTS company;
#创建部门表
CREATE TABLE dept(
id INT PRIMARY KEY AUTO_INCREMENT,
`name` VARCHAR(20)
);
#往部门表中插入多条数据
INSERT INTO dept(`name`) VALUES ('研发部'),('销售部'),('财务部');
#查询部门表中数据
SELECT * FROM dept;
#创建员工表
CREATE TABLE employee(
id INT PRIMARY KEY AUTO_INCREMENT,
`name` VARCHAR(10),
address VARCHAR(30),
age INT,
sex CHAR(1),
dept_id INT,
FOREIGN KEY (dept_id) REFERENCES dept(id) #外键,关联部门表(部门表的主键)
);
#往员工表中插入多条员工信息
INSERT INTO employee VALUES
(NULL,'小明','南昌',24,'男',1),
(NULL,'小红','九江',20,'女',1),
(NULL,'小兰','抚州',19,'女',2),
(NULL,'小龙','宜春',18,'男',2),
(NULL,'小军','赣州',23,'男',3);
#查询员工表中的数据
SELECT * FROM employee;
部门表:
员工表:
一、多表查询
1.1 完成多表操作的两种方式:
(1)通过表连接查询
(2)通过子查询
1.2 笛卡尔积现象
- 什么是笛卡尔积:
-- 需求:查询所有的员工和所有的部门
SELECT * FROM dept,employee;
结果如下:
结果分析:左表是部门表,右表是员工表,左表中每一行记录与右表中的每一行记录全都匹配一次。
结果的行数=左表中行数x右表中行数
1.3 清除笛卡尔积现象的影响
-- 设置过滤条件
-- 指定过滤条件 主表.主键=从表.外键
SELECT * FROM dept,employee WHERE dept.id = employee.dept_id;
--可以给表起别名
SELECT * FROM dept d,employee e WHERE d.id = e.dept_id;
结果如下:
注:以上过滤以后的结果成为隐式内连接
二、内连接
2.1 隐式内连接
- 概念:看不到JOIN关键字,条件使用WHERE指定;上述解决笛卡尔积现象的案例就是隐式内连接。
2.2 显式内连接
- 概念:无论是显式内连接还是隐式内连接其查询结果是一样的,只是写法不同。显式内连接使用INNER JOIN …ON语句,可以省略INNER
select 列名 from 左表 inner join 右表 on 主表.主键=从表.外键
SELECT * FROM dept INNER JOIN employee ON dept.id = employee.dept_id;
- 案例:查询小龙的信息,显示员工id,姓名,地址,年龄和所在的部门名称,我们发现需要联合2张表同时才能查询出需要的数据,使用内连接
SELECT e.id,e.name,e.address,e.age,d.name --(4)
FROM employee e INNER JOIN dept d --(1)
ON d.id = e.dept_id --(2)
WHERE e.name = "小龙"; --(3)
结果如下:
2.3 内连接查询步骤:
(1)确定查询哪些表
(2)确定表连接的条件,通常是 主表.主键=从表.外键
(3)确定查询条件
(4)确定查询的列
三、左外连接
左连接的概念:查询的数据以左表为准,即使在其他表中没有匹配的记录也会显示出来。
select 列名 from 左表 left join 右表 on 表连接条件
注:左外连接使用LEFT OUTER JOIN … ON,其中OUTER可以省略
- 案例:在部门表中增加一个行政部,需要查询所有的部门和员工,将部门表设置成左表,员工表设置成右表;比较内连接和左外连接的区别。
(1)内连接查询
--向部门表插入行政部
INSERT INTO dept VALUE(NULL,"行政部");
--内连接
SELECT * FROM dept d INNER JOIN employee e ON d.id = e.dept_id
结果如下:
结果分析:可以看出在使用内连接的情况下与员工表没有匹配记录的行政部不见了
(2)左连接查询
#左外连接
SELECT * FROM dept d LEFT JOIN employee e ON d.id = e.dept_id
结果如下:
结果分析:左表的数据全部显示出来,而右表中如没以左表匹配的记录则显示为null。
四、右外连接
右连接的概念:查询的数据以右表为准,即使在其他表中没有匹配的记录也会显示出来
select 列名 from 左表 right join 右表 on 表连接条件
注:右外连接使用RIGHT OUTER JOIN … ON, 其中OUTER可以省略
- 案例:在员工表中增加一个员工,但该员工还未分配部门;比较内连接和右外连接的区别。
--在员工表中插入一个未分配部门的员工信息
INSERT INTO employee VALUE(NULL,"小赵","吉安",26,"男",NULL);
SELECT * FROM employee;
结果如下:
(1)内连接查询
--内连接查询
SELECT * FROM dept d INNER JOIN employee e ON d.id = e.dept_id;
结果如下:
结果分析:可以看出在使用内连接的情况下与部门表没有匹配记录的员工小赵不见了。
(2)右外连接查询
--右外连接查询
SELECT * FROM dept d RIGHT JOIN employee e ON d.id = e.dept_id;
结果如下:
结果分析:右表的数据全部显示出来,而左表中如没以右表匹配的记录则显示为null。
五、全连接
根据上面简述,我们知道左连接是无论如何左表的数据都能够显示全,右连接是右表的数据无论如何都能够显示全,那么如果我们希望左表和右表的数据都能够显示全面呢(在对方表中没有匹配的数据就以null补齐)?这种连接查询我们称之为全连接(full join),但是很遗憾,MySQL并没有提供全连接,但Oracle支持;
虽然MySQL不支持全连接,但是我们可以利用MySQL提供的其它功能来完成全连接的功能:left join + right join
SELECT * FROM dept d LEFT JOIN employee e ON d.id = e.dept_id
UNION --union 是并集的意思
SELECT * FROM dept d RIGHT JOIN employee e ON d.id =e.dept_id;
结果如下: