MySQL はマルチテーブル クエリをどのように実装しますか?

  • 一緒に創造し、一緒に成長しましょう!「ナゲッツデイリー新企画・8月アップデートチャレンジ」に参加して4日目です。

序文:

意味:マルチテーブル クエリ (連想クエリとも呼ばれます) は、クエリ操作を一緒に完了するために 2 つ以上のテーブルを参照します。

前提条件:一緒にクエリされるこれらのテーブルは関連しており (1 対 1、1 対多)、それらの間に関連付けられたフィールドが存在する必要があります。この関連付けられたフィールドには、外部キーが確立されている場合と、確立されていない場合があります。たとえば、従業員テーブルと部門テーブル、これら 2 つのテーブルは「部門番号」によって関連付けられています。

複数テーブルクエリの分類:

分類 1: 等価接続と非等価接続

同等の接続:

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;
复制代码

等価結合の詳細:

  • 複数の結合条件が AND 演算子とともに使用されている
  • 複数のテーブルに同じ列がある場合、列名の前にテーブル名を付ける必要があります。
  • エイリアスを使用するとクエリが簡素化されます。
  • 列名の前にテーブル名のプレフィックスを使用すると、クエリの効率が向上します。
  • 元のテーブル名は使用できないことに注意してください如果我们使用了表的别名,在查询字段中、过滤条件中就只能使用别名进行代替。使用しないとエラーが報告されます。

アリ開発仕様:

[ 强制] データベース内のテーブル レコードのクエリと変更の場合、複数のテーブルが関係する限り、修飾するにはテーブルの別名 (またはテーブル名) を列名の前に追加する必要があります。

n 個のテーブルが接続されている場合、少なくとも n-1 個の接続条件が必要です。たとえば、3 つのテーブルを結合するには、少なくとも 2 つの結合条件が必要です。

非等価結合

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;
复制代码

分類 2: 自己結合と非自己結合

ほとんどのクエリは非自己結合です

自己結合クエリ:

#查询出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';
复制代码

クエリ結果の部分的な情報:

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

カテゴリ 3: 内部結合と外部結合

  • 内部結合: 2 つ以上のテーブルの行を同じ列と結合します。**结果集中不包含一个表与另一个表不匹配的行**これには特別な注意が必要です。

  • 外部結合: 2 つのテーブルの結合プロセス中に、結合条件を満たす行を返すだけでなく、左 (または右) のテーブルの条件を満たさない行も返します 。この接続は左 (または右) と呼ばれます。 ) 外部結合一致する行がない場合、結果テーブルの対応する列は空 (NULL) になります。

  • 左外部結合の場合、結合条件の左側のテーブルも と呼ばれ主表、右側のテーブルも と呼ばれます从表

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

因为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、等值连接使用时的细节。

おすすめ

転載: juejin.im/post/7128337573990105096