How does MySQL implement multi-table query?

  • Create together and grow together! This is the 4th day of my participation in the "Nuggets Daily New Project·August Update Challenge".

Foreword:

Meaning: Multi-table query, also called associative query, refers to two or more tables to complete the query operation together.

Precondition: These tables queried together are related (one-to-one, one-to-many), and there must be associated fields between them. This associated field may or may not have a foreign key established. For example: employee table and department table, these two tables are related by "department number".

Classification of multi-table queries:

Classification 1: Equivalent connection vs non-equivalent connection

Equivalent connection:

SELECT t1.employee_id, t1.last_name, 
       t2.department_id, t2.location_id
FROM   employees t1, departments t2
WHERE  t1.department_id = t2.department_id;
复制代码

Equijoin details:

  • Multiple join conditions are used with the AND operator
  • When multiple tables have the same column, the column name must be prefixed with the table name
  • Using aliases simplifies queries.
  • Using table name prefix before column name can improve query efficiency.
  • It should be noted that, 如果我们使用了表的别名,在查询字段中、过滤条件中就只能使用别名进行代替, the original table name cannot be used, otherwise an error will be reported.

Ali development specification:

[ 强制] For the query and modification of table records in the database, as long as multiple tables are involved, the alias (or table name) of the table needs to be added before the column name to qualify.

If n tables are connected, at least n-1 connection conditions are required. For example, to join three tables, at least two join conditions are required.

non-equivalence join

SELECT e.last_name, e.salary, j.grade_level
FROM   employees e, job_grades j
WHERE  e.salary BETWEEN j.lowest_sal AND j.highest_sal;
复制代码

Classification 2: Self-join vs non-self-join

Most queries are non-self joins

Self-join query:

#查询出last_name为 ‘Chen’ 的员工的 manager 的信息。
#因为manager本身也是员工,所以要用自连接查询
SELECT t2.* 
FROM employees t1
INNER JOIN employees t2
ON t1.manager_id = t2.employee_id
WHERE t1.last_name = 'Chen';
复制代码

Partial information of query results:

-------+----------+----------------+------------+---------------+
| employee_id | first_name | last_name | email    | phone_number |  
+-------------+------------+-----------+----------+--------------+
|         108 | Nancy      | Greenberg | NGREENBE | 515.124.4569 | 
+-------------+------------+-----------+----------+--------------+
复制代码

Category 3: Inner join vs Outer join

  • Inner join: Merge the rows of two or more tables with the same column, **结果集中不包含一个表与另一个表不匹配的行**this requires special attention.

  • Outer join: During the join process of two tables, in addition to returning rows that meet the join conditions, they also return rows that do not meet the conditions in the left (or right) table . This connection is called a left (or right) outer join . When there are no matching rows, the corresponding column in the result table is empty (NULL).

  • If it is a left outer join, the table on the left in the join condition is also called 主表, and the table on the right is called 从表.

  • 如果是右外连接,则连接条件中右边的表也称为主表,左边的表称为从表

因为MySQL不支持SQL92的部分语法,所有只要学会SQL99语法就OK了,就用SQL99语法来实现多表查询

  • 内连接(INNER JOIN)的实现

语法

#INNER 可以不写
SELECT 字段列表
FROM A表 INNER JOIN B表
ON 关联条件
WHERE 等其他子句;
复制代码

举例:

#这个是三表内连接查询
SELECT employee_id, city, department_name
FROM   employees e 
JOIN   departments d
ON     d.department_id = e.department_id 
JOIN   locations l
ON     d.location_id = l.location_id;
复制代码
  • 外连接(OUTER JOIN)的实现:

左外连接(LEFT OUTER JOIN)

语法:

#实现查询结果是A,即 A是主表
SELECT 字段列表
FROM A表 LEFT JOIN B表
ON 关联条件
WHERE 等其他子句;
复制代码

举例:

#OUTER 可以不写
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) ;
复制代码

查询结果: 在这里插入图片描述

需要注意的是:因为有的员工没有部门,所以当使用左外连接时,会查到107条记录;若使用的是内连接查询,就会有少一条记录,从这里就应该明白内连接与外连接的根本区别。

右外连接(RIGHT OUTER JOIN)

语法:

#实现查询结果是B
SELECT 字段列表
FROM A表 RIGHT JOIN B表
ON 关联条件
WHERE 等其他子句;
复制代码

举例:

#此时departments是主表
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;

#也可以写成
SELECT e.last_name, e.department_id, d.department_name
FROM departments d
LEFT JOIN employees e
ON e.department_id = d.department_id ;
复制代码

满外连接(FULL OUTER JOIN)

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

具体可以看这篇文章:UNION、UNION ALL以及7种SQL JOINS的实现

课后练习题加强:

# 查询哪些部门没有员工 
SELECT t2.department_name
FROM employees t1
RIGHT JOIN departments t2
ON t1.`department_id` = t2.`department_id`
WHERE t1.`employee_id` IS NULL;

SELECT t2.department_name
FROM departments t2
LEFT JOIN employees t1
ON t1.`department_id` = t2.`department_id`
WHERE t1.`employee_id` IS NULL;
复制代码
#查询哪个城市没有部门 
SELECT t1.city
FROM locations t1
LEFT JOIN departments t2
ON t1.`location_id` = t2.`location_id`
WHERE t2.`department_id` IS NULL;
复制代码

爱在结尾:主要学习了:1、多表查询的三个分类;2、要区分内连接、外连接的不同之处;3、等值连接使用时的细节。

Guess you like

Origin juejin.im/post/7128337573990105096