MySQL——连接查询

一、含义

又称多表查询,即当查询中涉及到了多个表的字段,需要使用多表连接。
如果这样写法,将会导致笛卡尔乘积现象

SELECT
	字段 1,字段2 
FROM1,表2,
	...;

笛卡尔乘积现象: 当查询多个表时,没有添加有效的连接条件,导致多个表所有行实现完全连接(表1有m行,表2有n行,结果有m*n行)
发生原因: 没有有效的连接条件
如何解决: 添加有效的连接条件

二、分类

1.按年代分类:
sql92标准:仅仅支持内连接
sql99标准【推荐使用】:支持内连接、外连接(左外,右外)、交叉连接

2.按功能分类
内连接:等值、非等值、自连接
外连接:、左外、右外、全外(mysql不支持)
交叉连接

三、SQL92标准

1、等值连接

语法:

SELECT
	查询列表 
FROM1 别名,2 别名 
WHERE1.key =2.keyAND 筛选条件】
	【 GROUP BY分组字段】
	【 HAVING分组后的筛选】
	【 ORDER BY排序字段】;

案例1:查询女神名对应的男神名
测试表:
MySQL——连接查询_第1张图片

SELECT
	`name`,
	boyName 
FROM
	beauty,
	boys 
WHERE
	beauty.boyfriend_id = boys.id;

案例2:查询员工名对应的部门名

SELECT
	last_name,
	department_name 
FROM
	employees,
	departments 
WHERE
	employees.department_id = departments.department_id;

案例3:查询员工名、工种号、工种名

SELECT
	last_name,
	j.job_id,
	job_title 
FROM
	employees AS e,
	jobs AS j 
WHERE
	e.job_id = j.job_id;

案例4:查询有奖金的员工名、部门名

SELECT
	last_name,
	department_name 
FROM
	employees,
	departments 
WHERE
	employees.department_id = department.department_id 
	AND employees.commission_pct IS NOT NULL;

案例5:查询每个城市的部门个数

SELECT
	city AS 个数,
	COUNT(*) 
FROM
	location AS l,
	departments AS d 
WHERE
	l.department_id = d.department_id 
GROUP BY
	city;

案例6:查询有奖金的每个部门的部门名和部门的领导编号和该部门的最低工资

SELECT
	department_name,
	d.manager_id,
	MIN( salary ) 
FROM
	departments AS d,
	employees AS e 
WHERE
	d.departmrnt_id = e.department_id 
	AND e.commission_pct IS NOT NULL 
GROUP BY
	department_name,
	d.manager_id;

特点:
① 一般为表起别名
②多表的顺序可以调换
③n表连接至少需要n-1个连接条件
④等值连接的结果是多表的交集部分

2、非等值连接

语法:

SELECT
	查询列表 
FROM1 别名,2 别名 
WHERE
	非等值的连接条件
	【 AND 筛选条件】
	【 GROUP BY分组字段】
	【 HAVING分组后的筛选】
	【 ORDER BY排序字段】;

案例:查询员工的工资和工资级别

SELECT
	salary,
	grade_level 
FROM
	employees AS e,
	job_grades AS j 
WHERE
	e.salary BETWEEN j.lowest_sal 
	AND j.highest_sal;

3、自连接

语法:

SELECT
	查询列表 
FROM
	表 别名 1,表 别名 2 
WHERE
	等值的连接条件
	【 AND 筛选条件】
	【 GROUP BY分组字段】
	【 HAVING分组后的筛选】
	【 ORDER BY排序字段】;

案例:查询员工名和上级的名称

SELECT
	e.last_name,
	m.last_name 
FROM
	employee AS e,
	employees AS m 
WHERE
	e.manager_id = m.employee_id;

四、SQL99标准

1、内连接inner

语法:

SELECT
	查询列表 
FROM1 别名
	INNER JOIN2 别名 ON 连接条件 
WHERE
	筛选条件 
GROUP BY
	分组列表 
HAVING
	分组后的筛选 
ORDER BY
	排序列表 
	LIMIT 子句;

特点:
①表的顺序可以调换
②内连接的结果=多表的交集
③n表连接至少需要n-1个连接条件

分类:
等值连接

#案例1:查询员工名、部门名(调换位置)
SELECT
	last_name,
	department_name 
FROM
	employees e
	INNER JOIN departments d ON e.department_id = d.department_id;
#案例2:查询名字中包含e的员工名和工种名
SELECT
	last_name,
	job_title 
FROM
	employees e
	INNER JOIN jobs j ON e.job_id = j.job_id 
WHERE
	e.last_name LIKE '%e%';
#案例:查询部门个数>3的城市名和部门个数
SELECT
	city,
	COUNT(*) 部门个数 
FROM
	departments d
	INNER JOIN locations l ON d.location_id = l.location.id 
GROUP BY
	city 
HAVING
	COUNT(*) >;

非等值连接

#案例1:查询员工的工资级别
SELECT
	salary,
	grade_level 
FROM
	employees e
	INNER JOIN job_grades j ON e.salary BETWEEN j.lowest_sal 
	AND highest_sal; 
#案例2:查询每个工资级别个数>20的个数,并且按工资级别降序
SELECT
	count(*),
	grade_level 
FROM
	employees e
	INNER JOIN job_grades j ON e.salary BETWEEN j.lowest_sal 
	AND highest_sal 
GROUP BY
	grade_level 
HAVING
	count(*)> 20 
ORDER BY
	grade_level DESC;

自连接

#案例:查询员工的名字、上级的名字
SELECT
	e.last_name,
	m.last_name 
FROM
	employees e
	INNER JOIN employees m ON e.manager_id = m.employee_id;

2、外连接

应用场景:用于查询一个表中有,另一个表中没有的记录

左外连接:left【outer】
右外连接:right【outer】
全外连接:full【outer】

语法:

SELECT
	查询列表 
FROM1 别名 LEFT | RIGHT |
	FULLOUTERJOIN2 别名 ON 连接条件 
WHERE
	筛选条件 
GROUP BY
	分组列表 
HAVING
	分组后的筛选 
ORDER BY
	排序列表 
	LIMIT 子句;
#案例:查询哪个部门没有员工
#左外连接
SELECT
	d.*,
	e.employee_id 
FROM
	departments d
	LEFT OUTER JOIN employees e ON d.department_id = e.department_id 
WHERE
	e.employee_id IS NULL;
	
#右外连接
SELECT
	d.*,
	e.employee_id 
FROM
	employees e
	LEFT OUTER JOIN departments d ON d.department_id = e.department_id 
WHERE
	e.employee_id IS NULL;
	

特点:
①查询的结果=主表中所有的行,如果从表和它匹配的将显示匹配行,如果从表没有匹配的则显示null
②left join 左边的就是主表,right join 右边的就是主表,full join 两边都是主表
③一般用于查询除了交集部分的剩余的不匹配的行
④全外连接=内连接的结果+表1中有但表2中没有的+表2中有但表1中没有的

3、交叉连接cross

语法:

SELECT
	查询列表 
FROM1 别名
	CROSS JOIN2 别名;

特点: 类似于笛卡尔乘积

4、不同连接

MySQL——连接查询_第2张图片

你可能感兴趣的:(MySQL)