当前位置:   article > 正文

MYSQL多表连接查询

mysql多表连接查询

多表查询,也称为关联查询,指两个或更多个表一起完成查询操作。
前提条件:这些一起查询的表之间是有关系的(一对一、一对多),它们之间一定是有关联字段,这个
关联字段可能建立了外键,也可能没有建立外键。比如:员工表和部门表,这两个表依靠“部门编号”进
行关联。

从多个表获取数据

 

#案例:查询员工的姓名及其部门名称
SELECT last_name, department_name
FROM employees, departments;

 

 查询结果:
#案例:查询员工的姓名及其部门名称
SELECT last_name, department_name
FROM employees, departments;
+-----------+----------------------+
| last_name | department_name   |
+-----------+----------------------+
| King   | Administration    |
| King   | Marketing      |
| King   | Purchasing      |
| King   | Human Resources   |
| King   | Shipping       |
| King   | IT          |
| King   | Public Relations   |
| King   | Sales        |
| King   | Executive      |
| King   | Finance       |
| King   | Accounting      |
| King   | Treasury       |
...
| Gietz   | IT Support      |
| Gietz   | NOC         |
| Gietz   | IT Helpdesk     |
| Gietz   | Government Sales   |

分析错误情况:

SELECT COUNT(employee_id) FROM employees;
#输出107行
SELECT COUNT(department_id)FROM departments;
#输出27行
SELECT 107*27 FROM dual;
我们把上述多表查询中出现的问题称为:笛卡尔积的错误。

SQL92中,笛卡尔积也称为 交叉连接 ,英文是 CROSS JOIN 。在 SQL99 中也是使用 CROSS JOIN表示交
叉连接。它的作用就是可以把任意表进行连接,即使这两张表不相关。

笛卡尔积的错误会在下面条件下产生:
省略多个表的连接条件(或关联条件)
连接条件(或关联条件)无效
所有表中的所有行互相连接
为了避免笛卡尔积, 可以在 WHERE 加入有效的连接条件。
加入连接条件后,查询语法: 

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

多表连接的细节:

多个表中有相同列时,必须在列名之前加上表名前缀。
在不同表中具有相同列名的列可以用 表名 加以区分

连接 n个表,至少需要n-1个连接条件。比如,连接三个表,至少需要两个连接条件。

使用别名可以简化查询。
列名前使用表名前缀可以提高查询效率。

对于数据库中表记录的查询和变更,只要涉及多个表,都需要在列名前加表的别名(或
表名)进行限定。
说明 :对多表进行查询记录、更新记录、删除记录时,如果对操作列没有限定表的别名(或表
名),并且操作列在多个表中存在时,就会抛异常。
正例 :select t1.name from table_first as t1 , table_second as t2 where t1.id=t2.id;
反例 :在某业务中,由于多表关联查询语句没有加表的别名(或表名)的限制,正常运行两年
后,最近在 某个表中增加一个同名字段,在预发布环境做数据库变更后,线上查询语句出现出
1052 异常:Column 'name' in field list is ambiguous。

多表连接有多种说法

内连接: 合并具有同一列的两个以上的表的行, 结果集中不包含一个表与另一个表不匹配的行
外连接: 两个表在连接过程中除了返回满足连接条件的行以外还返回左(或右)表中不满足条件的
行 ,这种连接称为左(或右) 外连接。没有匹配的行时, 结果表中相应的列为空(NULL)。
如果是左外连接,则连接条件中左边的表也称为 主表 ,右边的表称为 从表 。
如果是右外连接,则连接条件中右边的表也称为 主表 ,左边的表称为 从表 。

内连接(INNER JOIN)的实现
语法:

SELECT 字段列表
FROM A表 INNER JOIN B表
ON 关联条件
WHERE 等其他子句;

题目1:
SELECT e.employee_id, e.last_name, e.department_id,
   d.department_id, d.location_id
FROM  employees e JOIN departments d
ON   (e.department_id = d.department_id)

左外连接(LEFT OUTER JOIN)
语法:

#实现查询结果是A
SELECT 字段列表
FROM A表 LEFT JOIN B表
ON 关联条件
WHERE 等其他子句;
举例:

SELECT e.last_name, e.department_id, d.department_name
FROM  employees e
LEFT OUTER JOIN departments d
ON  (e.department_id = d.department_id) ;


 右外连接(RIGHT OUTER JOIN)
语法:
FROM A表 RIGHT JOIN B表
ON 关联条件
WHERE 等其他子句;

举例:

SELECT e.last_name, e.department_id, d.department_name
FROM  employees e
RIGHT OUTER JOIN departments d
ON  (e.department_id = d.department_id)

满外连接(FULL OUTER JOIN)
满外连接的结果 = 左右表匹配的数据 + 左表没有匹配到的数据 + 右表没有匹配到的数据。
SQL99是支持满外连接的。使用FULL JOIN 或 FULL OUTER JOIN来实现。
需要注意的是,MySQL不支持FULL JOIN,但是可以用 LEFT JOIN UNION RIGHT join代替。

7种SQL JOINS的实现

 代码实现
#中图:内连接 A∩B
SELECT employee_id,last_name,department_name
FROM employees e JOIN departments d
ON e.`department_id` = d.`department_id`;


#左上图:左外连接
SELECT employee_id,last_name,department_name
FROM employees e LEFT JOIN departments d
ON e.`department_id` = d.`department_id`;


#右上图:右外连接
SELECT employee_id,last_name,department_name
FROM employees e RIGHT JOIN departments d
ON e.`department_id` = d.`department_id`;


#左中图:A - A∩B
SELECT employee_id,last_name,department_name
FROM employees e LEFT JOIN departments d
ON e.`department_id` = d.`department_id`
WHERE d.`department_id` IS NULL


#右中图:B-A∩B
SELECT employee_id,last_name,department_name
FROM employees e RIGHT JOIN departments d
ON e.`department_id` = d.`department_id`
WHERE e.`department_id` IS NULL

SELECT employee_id,last_name,department_name
FROM employees e LEFT JOIN departments d
ON e.`department_id` = d.`department_id`
WHERE d.`department_id` IS NULL
UNION ALL  #没有去重操作,效率高
SELECT employee_id,last_name,department_name
FROM employees e RIGHT JOIN departments d
ON e.`department_id` = d.`department_id`;


#右下图
#左中图 + 右中图 A ∪B- A∩B 或者 (A - A∩B) ∪ (B - A∩B)
SELECT employee_id,last_name,department_name
FROM employees e LEFT JOIN departments d
ON e.`department_id` = d.`department_id`
WHERE d.`department_id` IS NULL
UNION ALL
SELECT employee_id,last_name,department_name
FROM employees e RIGHT JOIN departments d
ON e.`department_id` = d.`department_id`
WHERE e.`department_id` IS NULL

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/690824
推荐阅读
相关标签
  

闽ICP备14008679号