目录
1.内连接(INNER JOIN)
含义:内连接返回两个表中满足连接条件的行组合。它基于连接条件,只选取两个表中相互匹配的记录,相当于取两个表的交集部分。
语法:
SELECT column_list
FROM table1
JOIN table2
ON table1.column_name = table2.column_name;
例子:假设有两个表,employees(员工表)和departments(部门表)。employees表中有employee_id(员工编号)、employee_name(员工姓名)和department_id(部门编号)列;departments表中有department_id(部门编号)和department_name(部门名称)列。
查询员工姓名及其所属部门名称:
SELECT employees.employee_name, departments.department_name
FROM employees
JOIN departments
ON employees.department_id = departments.department_id;
解释:JOIN关键字用于连接employees表和departments表,ON子句指定了连接条件,即两个表中的department_id列值相等的记录会被匹配并返回。SELECT子句选择了要返回的列,即员工姓名和部门名称。
2.左连接(LEFT JOIN)
含义:左连接返回左表(写在JOIN关键字左边的表)中的所有行,以及右表(写在JOIN关键字右边的表)中与左表连接条件匹配的行。如果右表中没有匹配的行,则对应的列会显示为NULL。
语法:
SELECT column_list
FROM table1
LEFT JOIN table2
ON table1.column_name = table2.column_name;
例子:
查询所有员工姓名及其所属部门名称,如果员工没有所属部门(部门表中无匹配记录),部门名称显示为NULL:
SELECT employees.employee_name, departments.department_name
FROM employees
LEFT JOIN departments
ON employees.department_id = departments.department_id;
解释:以employees表为左表,departments表为右表进行左连接。employees表中的所有记录都会被返回,对于有部门编号匹配的员工,会显示对应的部门名称;对于没有部门编号匹配(如部门编号为NULL或者在部门表中不存在对应的部门编号)的员工,部门名称列会显示为NULL。
3.右连接(RIGHT JOIN)
含义:右连接返回右表中的所有行,以及左表中与右表连接条件匹配的行。如果左表中没有匹配的行,则对应的列会显示为NULL。
语法:
SELECT column_list
FROM table1
RIGHT JOIN table2
ON table1.column_name = table2.column_name;
例子:
查询所有部门名称以及所属部门的员工姓名,如果部门没有员工(员工表中无匹配记录),员工姓名显示为NULL:
SELECT employees.employee_name, departments.department_name
FROM employees
RIGHT JOIN departments
ON employees.department_id = departments.department_id;
解释:以employees表为左表,departments表为右表进行右连接。departments表中的所有记录都会被返回,对于有员工编号匹配的部门,会显示对应的员工姓名;对于没有员工编号匹配(如部门刚创建还没有员工分配过来)的部门,员工姓名列会显示为NULL。
4.全连接(FULL JOIN)
含义:全连接返回左表和右表中的所有行。当某一行在另一个表中没有匹配行时,对应的列会显示为NULL。不过,MySQL 本身不直接支持FULL JOIN,但可以通过LEFT JOIN和RIGHT JOIN的组合来实现类似的效果。
语法(模拟):
SELECT column_list
FROM
(table1
LEFT JOIN table2
ON table1.column_name = table2.column_name)
UNION ALL
(table1
RIGHT JOIN table2
ON table1.column_name = table2.column_name
WHERE table1.column_name IS NULL);
例子:
查询所有员工姓名和部门名称,包括没有部门的员工和没有员工的部门,对应的姓名或部门名称列显示为NULL:
SELECT employees.employee_name, departments.department_name
FROM (employees
LEFT JOIN departments
ON employees.department_id = departments.department_id)
UNION ALL
(SELECT employees.employee_name, departments.department_name
FROM employees
RIGHT JOIN departments
ON employees.department_id = departments.department_id
WHERE employees.employee_name IS NULL);
解释:首先通过LEFT JOIN获取包括没有部门的员工在内的所有记录组合,然后通过RIGHT JOIN获取包括没有员工的部门在内的所有记录组合(通过WHERE子句排除已经在LEFT JOIN中出现的有员工的部门记录),最后使用UNION ALL将这两个结果集合并起来,得到全连接的效果。
5.交叉连接(CROSS JOIN)
含义:交叉连接返回两个表的笛卡尔积,即返回两个表中所有行的组合。如果表 1 有m行,表 2 有n行,那么交叉连接后的结果集将有m * n行。
语法:
SELECT column_list
FROM table1
CROSS JOIN table2;
或者
SELECT column_list
FROM table1, table2;
(这种逗号分隔表的方式在没有连接条件时也表示交叉连接)
例子:
假设有一个colors表(包含color_id和color_name列)和一个shapes表(包含shape_id和shape_name列),查询所有颜色和形状的组合:
SELECT colors.color_name, shapes.shape_name
FROM colors
CROSS JOIN shapes;
解释:CROSS JOIN操作会将colors表中的每一行与shapes表中的每一行进行组合,返回所有可能的颜色和形状组合。如果colors表有 3 种颜色,shapes表有 4 种形状,那么结果集将有 3 * 4 = 12 行。