#连接查询


含义:
又称多表查询,当查询的字段来自于多个表时,就会用到连接查询

笛卡尔乘积现象:
表1 有m行,表2有n行,结果=m*n行

发生原因:没有有效的连接条件
如何避免:添加有效的连接条件

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

分类:
按年代分类:sq192标准:仅仅支持内连接
	    sq199标准:支持内连接+外连接(左外和右外)+交叉连接
按功能分类:
内连接:等值连接、非等值连接、自连接
外连接:左外连接、右外连接、全外连接
交叉连接

一、内连接

①等值连接:
语法:
	select 查询列表
	from 表名1 别名1,表名2,别名2
	where 等值连接的连接条件
特点:
	1、为了解决多表中的字段名重名问题,往往为表起别名,
	提高语义性
	2、表的顺序无要求
	


#一、简单的两表连接
USE `myemployees`

#查询员工名和部门名
SELECT e.last_name,d.`department_name`
FROM `employees` e,`departments` d
WHERE e.`department_id`=d.`department_id`;

#二、添加筛选条件

#查询部门编号>100的部门名和所在的城市名

SELECT `department_name`,`city`
FROM `departments` d,`locations` l
WHERE d.`location_id`=l.`location_id`
AND d.`department_id`>100;

#查询有奖金的员工名、部门名
SELECT `last_name`,`department_id`
FROM `departments` d,`employees` e
WHERE d.`department_id`=e.`department_id`
AND e.`commission_pct` IS NOT NULL;

#查询城市名汇总第二个字符为o的部门名和城市名

SELECT `department_name`,`city`
FROM `departments` d,`locations` l
WHERE d.`location_id`=l.`location_id`
AND city LIKE '_o%';

#三、添加分组+筛选
#查询每个城市的部门个数
SELECT COUNT(*) 部门个数,l.`city`
FROM `departments`d,`locations` l
WHERE d.`location_id`=l.`location_id`
GROUP BY l.`city`;

#②非等值连接

#查询部门编号在10-90之间的员工的工资级别,并按级别进行分组
SELECT COUNT(*) 个数,grade
FROM `employees` e
JOIN sal_grade g
ON e.`salary` BETWEEN g.`min_salary` AND g.`max_salary`
WHERE e.`department_id` BETWEEN 10 AND 90
GROUP BY g.grade;

#③自连接

#查询员工名和对应的领导名
SELECT e.`last_name`,m.`last_name`
FROM `employees` e
JOIN `employees` m
ON e.`manager_id`=m.`employee_id`;

#二、外连接

说明:查询结果为主表中所有的记录,
      如果从表有匹配项,则显示匹配项;
      如果从表中没有匹配项,则显示NULL

应用场景:一般用于查询主表中有但从表没有的记录

特点:
1、外连接分主从表,两表的顺序不能任意调换
2、左连接,左为主表。右连接,右为主表。

语法:
select 查询列表
from 表1 别名
left|right|full [outer] join 表2 别名
on 连接条件
where 筛选条件;

USE girls;
#查询所有女神记录,以及对应的男神名,如果没有对应的男神,则显示为null

#左连接
SELECT b.*,bo.*
FROM beauty b
LEFT JOIN boys bo ON b.`boyfriend_id`=bo.`id`;

#右连接
SELECT b.*,bo.*
FROM boys bo
RIGHT JOIN beauty b ON b.`boyfriend_id`=bo.`id`;

#查询哪个女神没有男朋友

#左连接
SELECT b.`name`
FROM `beauty` b
LEFT JOIN boys bo ON b.`boyfriend_id`=bo.`id`
WHERE bo.`id`;

#右连接
SELECT b.*,bo.*
FROM boys bo
RIGHT JOIN  `beauty` b ON b.`boyfriend_id`=bo.`id`
WHERE bo.`id` IS NULL;

#查询哪个部门没有员工,并显示其部门编号和部门名

SELECT COUNT(*) 部门个数 
FROM departments d
LEFT JOIN `employees` e ON d.`department_id`=e.`department_id`
WHERE e.`employee_id` IS NULL;