-
一緒に創造し、一緒に成長しましょう!「ナゲッツデイリー新企画・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、等值连接使用时的细节。