文章目录
表的内连和外连(重点)
表的连接分为内连和外连
内连接
内连接实际上就是利用where子句对两种表形成的笛卡儿积进行筛选,我们前面学习的查询都是内连接,也是在开发过程中使用的最多的连接查询。
笛卡尔积(Cartesian product)是数学中一个基本的运算,通常用来描述两个集合之间的组合关系。假设有两个集合
𝐴 和 𝐵,笛卡尔积 𝐴×𝐵是所有可能的有序对 (𝑎,𝑏),其中 𝑎 来自集合 𝐴,𝑏 来自集合 𝐵。
具体来说,笛卡尔积的定义如下:
例如,如果集合 𝐴 ={1,2} 和集合 𝐵={𝑥,𝑦},那么它们的笛卡尔积为:
语法:select 字段 from 表1 inner join 表2 on 连接条件 and 其他条件;
外连接
外连接分为左外连接和右外连接
左外连接
如果联合查询,左侧的表完全显示我们就说是左外连接。
语法:select 字段名 from 表名1 left join 表名2 on 连接条件
案例:
bash
-- 建两张表
create table stu (id int, name varchar(30)); -- 学生表
insert into stu values(1,'jack'),(2,'tom'),(3,'kity'),(4,'nono');
create table exam (id int, grade int); -- 成绩表
insert into exam values(1, 56),(2,76),(11, 8);
- 查询所有学生的成绩,如果这个学生没有成绩,也要将学生的个人信息显示出来
bash
-- 当左边表和右边表没有匹配时,也会显示左边表的数据
select * from stu left join exam on stu.id=exam.id;
右外连接
如果联合查询,右侧的表完全显示我们就说是右外连接。
语法:select 字段 from 表名1 right join 表名2 on 连接条件;
案例:
- 对stu表和exam表联合查询,把所有的成绩都显示出来,即使这个成绩没有学生与它对应,也要显示出来
bash
select * from stu right join exam on stu.id=exam.id;
练习:
- 列出部门名称和这些部门的员工信息,同时列出没有员工的部门
bash
方法一:
select d.dname, e.* from dept d left join emp e on d.deptno=e.deptno;
方法二:
select d.dname, e.* from emp e right join dept d on d.deptno=e.deptno;
简单回顾
内连接(Inner Join)
简要回顾:内连接是数据库中最常用的连接方式,它只返回两个表中匹配条件的记录。内连接默认会排除不匹配的数据行,因此它常用于查询两个表之间有逻辑关系的数据。
不同于笛卡尔积:尽管内连接涉及笛卡尔积的概念,但它对笛卡尔积进行了筛选(使用ON或WHERE子句来限制返回的数据)。笛卡尔积产生所有可能的组合,而内连接通过指定条件将其缩小为实际匹配的数据集。
多表连接:可以进行多表的内连接(例如三张及以上表),只要确保每个表之间有连接条件。例如
bash
SELECT a.name, b.salary, c.department
FROM employees a
INNER JOIN salaries b ON a.id = b.employee_id
INNER JOIN departments c ON a.department_id = c.id;
外连接(Outer Join)
外连接分为三种:左外连接、右外连接和全外连接(不过全外连接在MySQL中并不直接支持,可以通过联合查询的方式实现)。
左外连接(LEFT JOIN)
简要回顾:左外连接将返回左表的所有记录,即使它们在右表中没有匹配的记录。对于没有匹配的右表记录,右表的字段将显示NULL。
使用场景:左外连接常用于显示所有左表中的记录,即便它们在右表中没有相应的记录。例如,列出所有员工以及他们的销售数据,如果某个员工没有销售数据,也应该显示该员工的信息。
示例:
bash
SELECT employees.name, sales.amount
FROM employees
LEFT JOIN sales ON employees.id = sales.employee_id;
右外连接(RIGHT JOIN)
简要回顾:右外连接返回右表的所有记录,即使它们在左表中没有匹配的记录。对于没有匹配的左表记录,左表的字段将显示NULL。
使用场景:右外连接常用于显示所有右表中的记录,并显示左表匹配的记录(如果有的话)。例如,列出所有销售记录以及销售人员的信息,如果某个销售记录没有对应的员工信息,也会显示该销售记录。
示例:
bash
SELECT employees.name, sales.amount
FROM employees
RIGHT JOIN sales ON employees.id = sales.employee_id;
全外连接(FULL OUTER JOIN)
简要回顾:全外连接返回左表和右表的所有记录。如果某个表中没有匹配的记录,则该表的相关字段显示NULL。但是需要注意的是,MySQL 不直接支持全外连接,通常可以通过联合左外连接和右外连接来实现。
实现方式:
bash
SELECT * FROM table1
LEFT JOIN table2 ON table1.id = table2.id
UNION
SELECT * FROM table1
RIGHT JOIN table2 ON table1.id = table2.id;
连接条件
不同连接条件的选择:除了最常见的基于键的等值连接(=),你还可以使用其他条件进行连接,例如:
>、<、>=、<=,可以在连接条件中使用这些操作符进行非等值连接。
IS NULL 和 IS NOT NULL,可以用来连接包含或不包含NULL的记录。
使用多个连接条件:连接条件不一定只有一个,可以使用多个条件来确保数据的准确匹配。例如,连接条件可以是id和status两个字段的组合:
bash
SELECT *
FROM table1 t1
INNER JOIN table2 t2 ON t1.id = t2.id AND t1.status = t2.status;
连接的优化
索引优化:对于连接查询,确保连接字段上有索引,以提高查询的效率。如果连接字段没有索引,查询可能会变得非常慢,尤其是当表数据量非常大时。
避免笛卡尔积:当你忘记加连接条件时,MySQL会执行笛卡尔积,这会导致查询结果数目激增。因此,一定要小心连接条件的设置。
ON与WHERE的区别
- ON子句:用于指定连接条件,它是在连接过程中确定行是否匹配的条件。
- WHERE子句:用于进一步筛选结果集,可以用来过滤已连接的结果集中的行。
在内连接中,ON子句和WHERE子句通常是可以互换的,但是在外连接中,ON和WHERE的作用有所不同。使用WHERE会影响外连接的结果,可能会丢失左或右表的某些记录。因此,在外连接中,过滤条件应该尽量放在ON子句中,而非WHERE子句中。
MySQL特有的连接语法
自然连接(NATURAL JOIN):自然连接会根据两个表中具有相同名称的所有列进行连接。它可以简化SQL查询,但有时可能不如显式列出连接条件来得直观。
bash
SELECT * FROM table1 NATURAL JOIN table2;
使用USING进行连接:USING简化了多个列名的连接,可以自动匹配两个表中同名的列。
bash
SELECT *
FROM table1
INNER JOIN table2 USING(id);
连接的其他注意事项
自连接(Self Join):有时候需要将同一张表与自身进行连接,这称为自连接。自连接通常使用别名来区分同一张表的不同实例。
bash
SELECT a.name, b.name
FROM employees a
INNER JOIN employees b ON a.manager_id = b.id;
链式连接:可以将多个表通过多个连接进行链式连接。例如:
bash
SELECT a.name, b.salary, c.department
FROM employees a
INNER JOIN salaries b ON a.id = b.employee_id
INNER JOIN departments c ON b.department_id = c.id;