一、多表查询

【1】什么是多表查询?

  • 即,从多个表中获取数据。
  • 注意: 在多表查询是,如果列明在两个表中都有,那么列名前需要加上表名
  • sql优化:列名前最好加上表名,尤其在多表查询时

SELECT employees.`first_name`,employees.`department_id`
    departments.`department_id`,departments.`department_name`
FROM employees,departments  -- 错误,缺少连接条件
 -- 发生了笛卡尔集错误
 -- 愿因: 缺少多表之间的连接条件,或者连接条件错误

 SELECT e.first_name,e.department_id,-- 可以使用表的别名
    d.department_id,d.department_name
FROM employees e, departments d -- 错误,缺少连接条件

【2】关于笛卡尔集 :

  • 笛卡尔集会在下面条件下产生:

省略连接条件
连接条件无效
所有表中的所有行互相连接

为了避免笛卡尔集, 可以在 WHERE 加入有效的连接条件。

【3】使用笛卡尔集与不使用的对比

①查出所有数据

SELECT  * FROM employees
SELECT * FROM departments

②不使用笛卡尔集的普通子查询(MySQL连接

在 WHERE 子句中写入连接条件。
在表中有相同列时,在列名之前加上表名前缀

-- 需求: 查询每个员工所在部门的名称

SELECT employees.`first_name`,employees.`department_id`,
    departments.`department_id`,departments.`department_name`
FROM employees,departments
WHERE employees.`department_id`= departments.`department_id`

③使用JOIN ON 实现多表查询,解决笛卡尔集的问题

-- sq199规定了多表查询的规则
-- 使用 join on
-- 注意: 如果有n个表需要连表查询,那么至少得有n-12个连接条件

SELECT e.first_name,d.department_id,l.city
FROM employees e JOIN departments d
ON e.department_id = d.department_id
JOIN locations l
ON d.location_id = l.location_id

 

MySQL 连接

【1】自连接,非自链接

-- 自连接需求: 查找员工和员工的领导
SELECT e.first_name,m.first_name
FROM employees e JOIN employees m
ON e.`manager_id` = m.`employee_id`

-- 非自连接:两张不同的表进行连接查询

-- 等值连接,非等值连接
-- 等值连接案例
SELECT e.first_name,d.department_name
FROM employees e JOIN departments d
ON e.department_id = d.department_id

-- 非等值连接需求: 查看所有员工薪水的等级
SELECT e.first_name,e.`salary`,j.grade
FROM employees e JOIN job_grades j
ON e.`salary`>= j.lowest_sal AND e.`salary` <=j.highest_sal

【2】 内连接,外连接

-- 内连接

合并具有同一列的两个以上的表的行,结果集中不包含一个表与另一个表不匹配的行

-- 外连接: 左外连接 VS 右外连接

-- 左外连接: 两个表在连接过程中除了返回满足连接条件的行以外还返回左表中不满足条件的行
-- 这种连接成为左外连接

SELECT  e.`first_name`,e.`department_id`,d.department_name
FROM employees e LEFT OUTER JOIN departments d
ON e.`department_id` = d.department_id

-- 右外连接:两个表在连接过程中除了返回满足连接条件的行意外还返回右表中不满足条件的行
 -- 这种连接成为右外连接

SELECT e.`first_name`,e.`department_id`,d.department_id,d.department_name
FROM employees e RIGHT OUTER JOIN departments d
ON e.`department_id` = d.department_id

-- 满外连接 full join (mysql不支持)