内部結合: 同じ列を持つ 3 つ以上のテーブルの行をマージします。結果セット には、1 つのテーブルと別のテーブル が含まれません。 一致する行。
端的に言うと、クエリ結果には一致する行のみが含まれ、一致しない行は破棄されます。 [例] 従業員番号employee_id とそれに対応する部門名
Department_name をクエリします。このうち、部門名
Department_name は部門テーブル
Departments にのみ存在し、部門テーブル
Departments は次の図に示すとおりです。
##従業員テーブルemployees
と部門テーブルDepartmentsは、一致する部門番号
Department_idによって接続されています。クエリ コードは次のとおりです。
SELECT emp.`employee_id`, emp.`last_name`, dept.`department_name` FROM employees emp, departments dept WHERE emp.`department_id` = dept.`department_id`;
クエリ結果:
ここでは 106 レコードが返されますが、従業員テーブル employees# の合計数は返されません。 ## は 107 件のレコードがあり、1 人が不足しています。その理由は、次の図に示すように、従業員テーブル
employees に、部門番号 Department_id
が (NULL) である従業員が存在するためです。 #部門テーブル
Departments
には、値 (NULL) を持つ部門番号
が存在しないため、この行の不一致データは破棄され、表示されません。 。以下の図に示すように、内部結合には 2 つのテーブルの一致する行、つまり、以下の図の 2 つの円の交点のみが含まれます。 #この結合方法は内部結合と呼ばれます。
2. 外部結合外部結合: 同じ列を持つ 3 つ以上のテーブルの行をマージします。結果セットは、あるテーブルと別のテーブルに一致する行に加えて、Reached もクエリします。左側または右側のテーブル内の一致しない行。
外部結合は、次の 3 つのカテゴリに分類されます。
結合プロセス中に結合条件を満たす行を返すことに加えて、2 つのテーブル
left テーブル内の条件を満たさない行も返します。下の図に示すように、左外部結合は左側の円全体です。
右外部結合:
接続プロセス中、接続条件を満たす行を返すだけでなく、2 つのテーブルは
right も返します。完全外部結合:
テーブル接続プロセス中に、結合条件を満たす行を返すことに加えて、左側のテーブルと右側のテーブルは条件を満たさない行も返されます。以下の図に示すように、完全外部結合は 2 つの円のすべての部分です。
[例] 部門番号 Department_id
に基づいて、従業員テーブルemployees# の all
従業員番号をクエリします。Departments
内のそれに対応する部門名Department_name。
[分析] 質問に all
のクエリを必要とする単語がある場合は常に、非常に注意する必要があり、これは、クエリに外部結合を使用する必要があることを意味します。 SQL92 構文と SQL99 構文の両方を使用して外部結合を実装できます。詳細については、「5.9 よく使用される SQL 標準」(# 5.9 よく使用される SQL 標準) を参照してください。左側のテーブル従業員テーブル employees
には合計 107 個のデータがあり、右側のテーブルと左側のテーブルは 106 個のデータのみと一致するため、左外部結合を使用する必要があります。 [外部結合を実装するための SQL92 構文] ( )
を使用します。 <pre class="brush:sql;">SELECT emp.`employee_id`, emp.`last_name`, dept.`department_name`
FROM employees emp, departments dept
WHERE emp.`department_id` = dept.`department_id`(+);</pre>
クエリ結果: エラー
これは、MySQL が SQL92 構文の外部結合操作をサポートしていないためです。しかし、オラクルはそれをサポートしています。したがって、無駄な学習はありません。 MySQL は、複数テーブル クエリを実装するための SQL99 構文のみをサポートします。
3. 複数テーブル クエリを実装するための SQL99 構文
SQL99 は、1999 年に SQL によって公布された SQL 構文の標準仕様を指します。その後、一連の新しい SQL 標準がリリースされましたが、MySQL を学習する過程では、主に SQL99 と SQL92 をマスターすれば十分です。このセクションから始まる MySQL の学習は半分です。このセクションの前は SQL92 構文でしたが、このセクションからは SQL99 構文専用です。 <p>SQL99语法使用 <code>JOIN...ON
的方式实现多表查询,且可以同时实现内连接和三种外连接。MySQL是支持这种方式的。
【例子:三表查询】查询员工的员工编号 employee_id
、 姓名 last_name
、部门名称 department_name
和所在城市 city
。
【分析】这个需求需要 3 张表共同查询。
SELECT emp.`employee_id`, emp.`last_name`, dept.`department_name`, loc.`city` FROM employees emp JOIN departments dept ON emp.`department_id` = dept.`department_id` JOIN locations loc ON dept.`location_id` = loc.`location_id`;
SQL99语法就是加一张表,就 JOIN
一张表,并在 ON
后加连接条件。注意,这里的 JOIN
前面还省略了表示内连接的关键字 INNER
,在使用内连接时可以忽略。即代码还可以写成完整形式:
SELECT emp.`employee_id`, emp.`last_name`, dept.`department_name`, loc.`city` FROM employees emp INNER JOIN departments dept ON emp.`department_id` = dept.`department_id` JOIN locations loc ON dept.`location_id` = loc.`location_id`;
查询结果:
【例子】根据部门编号 department_id
,查询员工表 employees
中的所有员工编号 employee_id
和部门表 departments
中其对应的部门名称 department_name
。
【分析】由于左表是员工表 employees
,有107条数据;而右表是部门表 departments
,有27条数据。题目要求是返回所有员工的107条查询结果,因此这里使用左外连接。SQL99实现左连接接很简单,只需要在 JOIN
前加上两个关键字 LEFT OUTER
即可表示左外连接。如下代码所示:
SELECT emp.`employee_id`, emp.`last_name`, dept.`department_name` FROM employees emp LEFT OUTER JOIN departments dept ON emp.`department_id` = dept.`department_id`;
其中,OUTER
可以省略,即写成:
SELECT emp.`employee_id`, emp.`last_name`, dept.`department_name` FROM employees emp LEFT JOIN departments dept ON emp.`department_id` = dept.`department_id`;
查询结果:
举一反三地,右外连接就是在 OUTER JOIN
前加一个关键字 RIGHT
。
SELECT emp.`employeed/master/img/d`;
查询结果:
查询结果有122条记录,这怎么解释呢?再回想一下右外连接的定义:
两个表在连接过程中除了返回满足连接条件的行以外,还返回右表中不满足条件的行。如下图中,右外连接就是右边一整个圆。
就不难理解,因为右表部是没有人的。而左、右表匹配的数据有106条 (两圆相交部分) ,因此一共就有 106 + 16 = 122 106+16=122 106+16=122 条记录。如下图所示:
这个例子能更好地帮助我们理解右外连接。
举一反三地,满外连接就是在 OUTER JOIN
前加一个关键字 FULL
。但很不幸,MySQL不支持SQL99的满外连接语法,Oracle是支持的。
我们需要使用别的方法实现MySQL中的满外连接,详见4.6 满外连接 。
在开始本节之前,需要您了解SQL的 UNION
和 UNION ALL
的定义和实现。如果需要了解,可以阅读这篇博文:《MySQL中 UNION 并的使用》。
根据部门编号 department_id
,查询员工表 employees
中的员工编号 employee_id
和部门表 departments
中其对应的部门名称 department_name
。
SELECT emp.`employee_id`, emp.`last_name`, dept.`department_name` FROM employees emp JOIN departments dept ON emp.`department_id` = dept.`department_id`;
查询结果:
SELECT emp.`employee_id`, emp.`last_name`, dept.`department_name` FROM employees emp LEFT OUTER JOIN departments dept ON emp.`department_id` = dept.`department_id`;
查询结果:
SELECT emp.`employee_id`, emp.`last_name`, dept.`department_name` FROM employees emp RIGHT OUTER JOIN departments dept ON emp.`department_id` = dept.`department_id`;
SELECT emp.`employee_id`, emp.`last_name`, dept.`department_name` FROM employees emp LEFT OUTER JOIN departments dept ON emp.`department_id` = dept.`department_id` WHERE dept.`department_id` IS NULL;
查询结果:
作用是把员工表 employees
中,部门编号 department_id
为 (NULL) 的那一个员工查询出来了,如下图所示:
SELECT emp.`employee_id`, emp.`last_name`, dept.`department_name`, emp.`department_id` FROM employees emp RIGHT OUTER JOIN departments dept ON emp.`department_id` = dept.`department_id` WHERE emp.`department_id` IS NULL;
查询结果:
由于MySQL不支持SQL99语法的满外连接。因此,我们的实现方式就是求
4.2 左外连接 和 4.5 第五种JOIN 的并 UNION ALL
即可;或者求4.3 右外连接 和 4.4 第四种JOIN 的并 UNION ALL
也行,都是一样的效果。
# 方法一 SELECT emp.`employee_id`, emp.`last_name`, dept.`department_name` FROM employees emp LEFT OUTER JOIN departments dept ON emp.`department_id` = dept.`department_id` UNION ALL SELECT emp.`employee_id`, emp.`last_name`, dept.`department_id` FROM employees emp RIGHT OUTER JOIN departments dept ON emp.`department_id` = dept.`department_id` WHERE emp.`department_id` IS NULL; # 方法二 SELECT emp.`employee_id`, emp.`last_name`, dept.`department_name` FROM employees emp RIGHT OUTER JOIN departments dept ON emp.`employee_id` = dept.`department_id` UNION ALL SELECT emp.`employee_id`, emp.`last_name`, dept.`department_name` FROM employees emp LEFT OUTER JOIN departments dept ON emp.`employee_id` = dept.`department_id` WHERE dept.`department_id` IS NULL;
查询结果:
实现下面这个操作只需要把 4.4 第四种JOIN 和 4.5 第五种JOIN 求 UNION ALL
即可。
SELECT emp.`employee_id`, emp.`last_name`, dept.`department_name` FROM employees emp LEFT OUTER JOIN departments dept ON emp.`department_id` = dept.`department_id` WHERE dept.`department_id` IS NULL UNION ALL SELECT emp.`employee_id`, emp.`last_name`, dept.`department_name` FROM employees emp RIGHT OUTER JOIN departments dept ON emp.`department_id` = dept.`department_id` WHERE emp.`department_id` IS NULL;
查询结果:
以上がMySQLの内部結合、外部結合、SQL JOINSの実装方法は何ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。