1. 内部結合
2. 外部結合左外部結合:右外部結合:完全外部結合:
3. SQL99 構文を使用して複数テーブル クエリを実装する
3.1 SQL99 は内部接続を実装します
3.2 外部結合を実装するための SQL99 構文
3.2.1 左外部結合3.2.2 右外部結合
3.2.3 完全な外部接続
4. 概要: 7 つの SQL JOINS の実装
4.1 内部結合
4.2 左外部結合
4.3 右外部結合
4.4 4 番目の種類の JOIN
4.5 5 番目のタイプの JOIN
4.6 完全外部接続方法 1と方法 2
4.7 7 番目の JOIN
1. 内部結合
内部結合: 同じ列を持つ 3 つ以上のテーブルの行をマージします。結果セットには、あるテーブルの別のテーブルと一致しない行は含まれません。
人間の言葉で言えば、クエリ結果には一致する行のみが含まれ、一致しない行は破棄されます。
【例】 社員番号 employee_id
とそれに対応する部署名 を問い合わせますdepartment_name
。部門名は department_name
部門テーブルのみにあり departments
、部門テーブルは departments
次のようになります。
従業員テーブル employees
と部門テーブルは departments
部門番号一致で department_id
接続されています。クエリコードは次のとおりです。
SELECT 従業員ID、従業員姓、部門名 FROM 従業員、部門 WHERE 従業員ID = 部門ID;
検索結果:
ここでは 106 レコードが返されましたが、従業員テーブルには employees
合計 107 レコードがあり、1 人が欠落しています。その理由は 、 次の図に示すようにemployees
、従業員テーブルに部門番号が (NULL) の従業員が存在するためです 。department_id
ただし、部門テーブル departments
には値が (NULL) の部門番号がない department_id
ため、この行の不一致データは破棄され、表示されません。以下の図に示すように、内部結合には 2 つのテーブルの一致する行、つまり、以下の図の 2 つの円の交点のみが含まれます。
このタイプの接続は内部接続と呼ばれます。
2.外部接続
外部結合: 同じ列を持つ 2 つ以上のテーブルの行をマージします。結果セットは、あるテーブルと別のテーブルに一致する行に加えて、左側または右側のテーブル内の一致しない行もクエリします。
外部結合は次の 3 つのカテゴリに分類されます。
左外部結合:
2 つのテーブルの接続処理では、接続条件を満たす行が返されるだけでなく、左側のテーブルの条件を満たさない行も返されます。下の図に示すように、左外部結合は左側の円全体です。
右外部結合:
2 つのテーブルの接続処理では、接続条件を満たす行が返されるだけでなく、右側のテーブルの条件を満たさない行も返されます。下の図に示すように、右外部結合は右側の円全体です。
完全な外部接続:
2 つのテーブルの接続処理では、接続条件を満たす行が返されるだけでなく、左のテーブルと右のテーブルの条件を満たさない行も返されます。以下の図に示すように、完全外部結合は 2 つの円のすべての部分です。
[例] 部門番号に基づいて department_id
、 従業員テーブルemployees
内のすべての従業員番号 employee_id
と、 departments
それに対応する部門テーブル内の部門名を クエリしますdepartment_name
。
[分析] クエリを必要とする単語が質問中に出現した場合は 所有
、常に外部結合クエリを使用する必要があるため、非常に注意する必要があります。SQL92 構文と SQL99 構文の両方を使用して外部結合を実装できます。詳細については、「5.9 よく使用される SQL 標準」(# 5.9 よく使用される SQL 標準) を参照してください。左側のテーブルの従業員テーブル employees
には 107 個のデータがあり、右側のテーブルと左側のテーブルの間で一致するデータは 106 個のみであるため、左外部結合を使用する必要があります。
[外部結合を実装するには SQL92 構文] を使用します (+)
。
SELECT 従業員ID、従業員姓、部門名 FROM 従業員、部門 WHERE 従業員ID = 部門ID(+);
クエリ結果: エラーレポート
これは、MySQL が SQL92 構文での外部結合操作をサポートしていないためです。しかし、オラクルはそれをサポートしています。したがって、無駄な学習はありません。MySQL は、複数テーブル クエリを実装するための SQL99 構文のみをサポートします。
3. SQL99 構文を使用して複数テーブル クエリを実装する
SQL99 は、1999 年に SQL によって発行された SQL 構文の標準仕様を指します。その後、一連の新しい SQL 標準がリリースされましたが、MySQL を学習する過程では、主に SQL99 と SQL92 をマスターすれば十分です。このセクションから始まる MySQL の学習は半分です。このセクションの前は SQL92 構文でしたが、このセクションからは SQL99 構文専用です。
複数テーブルのクエリの実装にはSQL99 構文が使用され JOIN...ON
、内部結合と 3 つの外部結合を同時に実現できます。MySQL はこの方法をサポートしています。
3.1 SQL99 は内部接続を実装します
[例: 3 つのテーブルのクエリ] 従業員の従業員番号 employee_id
、名前 last_name
、部門名 department_name
、市区町村 をクエリしますcity
。
[分析] この要件では、3 つのテーブルを一緒にクエリする必要があります。
SELECT emp.`従業員ID`、従業員`姓`、部門`部門名`、loc.`市区町村` FROM 従業員 emp JOIN部門 dept ON emp.`部門ID` = 部門`部門ID` JOIN場所 loc ON dept.`location_id ` = loc.`location_id`;
SQL99 構文では、テーブルを JOIN
1 つだけ追加し、 ON
最後に接続条件を追加します。JOIN
内部接続を示すキーワードも ここでは 省略されていることに注意してくださいINNER
。内部接続を使用する場合は無視できます。つまり、コードは完全な形式で記述することもできます。
SELECT emp.`従業員ID`、従業員`姓`、部門`部門名`、loc.`市区町村` FROM 従業員 emp INNER JOIN部門 dept ON emp.`部門ID` = 部門`部門ID` JOIN場所 loc ON dept.` location_id` = loc.`location_id`;
検索結果:
3.2 外部結合を実装するための SQL99 構文
3.2.1 左外部結合
[例] 部門番号に基づいて department_id
、 従業員テーブルemployees
内のすべての従業員番号 employee_id
と、 departments
それに対応する部門テーブル内の部門名を クエリしますdepartment_name
。
【分析】 左のテーブルは従業員テーブルなので employees
データ数は107個、右のテーブルは部門テーブルな departments
のでデータ数は27個です。質問の要件は、すべての従業員に対して 107 個のクエリ結果を返すことであるため、ここでは左外部結合が使用されます。 SQL99 での左結合の実装は非常に簡単で、左外部結合を表すために必要なキーワードを 2 つ JOIN
前に 。LEFT OUTER
次のコードに示すように:
SELECT emp.`従業員ID`、emp.`姓`、部門`部門名` FROM 従業員 emp LEFT OUTER JOIN 部門部門 ON emp.`部門ID` = 部門`部門ID`;
そのうち、OUTER
省略することもできます。つまり、次のように記述できます。
SELECT emp.`従業員ID`、emp.`姓`、部門`部門名` FROM 従業員 emp LEFT JOIN 部門部門 ON emp.`部門ID` = 部門`部門ID`;
検索結果:
3.2.2 右外部結合
同様に、右外部結合はキーワード OUTER JOIN
を前に RIGHT
。
SELECT emp.`employeed/master/img/d`;
検索結果:
クエリ結果には 122 件のレコードがあります。これはどう説明すればよいでしょうか? 右外部結合の定義を思い出してください。
2 つのテーブルの接続処理では、接続条件を満たす行が返されるだけでなく、右側のテーブルの条件を満たさない行も返されます。下の図に示すように、右外部結合は右側の円全体です。
右側には誰もいないので、理解するのは難しくありません。左右のテーブル (2 つの円の交点) には一致するデータが 106 件あるため、合計 106 + 16 = 122 106+16=122 106+16=122 レコードがあります。以下に示すように:
この例は、右外部結合を理解するのに役立ちます。
3.2.3 完全な外部接続
他のケースについて推論を引き出すには、完全な外部接続では OUTER JOIN
前に FULL
。残念ながら、MySQL は SQL99 の完全な外部結合構文をサポートしていませんが、Oracle はサポートしています。
MySQL で完全な外部接続を実装するには、他の方法を使用する必要があります。詳細については、「4.6 完全な外部接続」を参照してください。
4. 概要: 7 つの SQL JOINS の実装
UNION
このセクションを始める前に、 SQL における sum の定義と実装を理解する必要があります UNION ALL
。さらに詳しく知りたい場合は、ブログ投稿「MySQL での UNION の使用」を参照してください。
4.1 内部結合
部門番号に基づいて department_id
、 employee テーブルemployees
の従業員番号 employee_id
と、 部門テーブルdepartments
のそれに対応する部門名を クエリしますdepartment_name
。
SELECT emp.`従業員ID`、emp.`姓`、部門`部門名` FROM 従業員 emp JOIN部門部門 ON emp.`部門ID` = 部門`部門ID`;
検索結果:
4.2 左外部結合
SELECT emp.`従業員ID`、emp.`姓`、部門`部門名` FROM 従業員 emp LEFT OUTER JOIN 部門部門 ON emp.`部門ID` = 部門`部門ID`;
検索結果:
4.3 右外部結合
SELECT emp.`従業員ID`、emp.`姓`、部門`部門名` FROM 従業員 emp RIGHT OUTER JOIN 部門部門 ON emp.`部門ID` = 部門`部門ID`;
4.4 4 番目の種類の JOIN
SELECT 従業員ID、従業員姓、部門名 FROM 従業員 従業員 LEFT OUTER JOIN 部門部門 ON 従業員部門ID = 部門ID` WHERE 部門ID` IS NULL;
検索結果:
この機能は、次の図に示すように、従業員テーブル employees
内の部門番号が (NULL) である department_id
従業員をクエリすることです。
4.5 5 番目のタイプの JOIN
SELECT 従業員ID、従業員姓、部門名、部門ID FROM 従業員 従業員 RIGHT OUTER JOIN 部門部門 ON 従業員部門ID = 部門ID WHERE 部門ID`無効である;
検索結果:
4.6 完全な外部接続
MySQL は SQL99 構文を使用した完全な外部接続をサポートしていないためです。したがって、私たちの実装方法は次のとおりです。
4.2 の左外部結合と 4.5 の 5 番目の JOIN の結合 UNION ALL
、または 4.3 右外部結合と 4.4 の 4 番目の JOIN の UNION ALL
結合を実行でき、どちらも同じ効果があります。
方法 1
方法 2
# 方法一 SELECT emp.`従業員ID`, emp.`姓`, 部門`部門名` FROM 従業員 emp LEFT OUTER JOIN 部門 dept ON emp.`部門ID` = 部門`部門ID` UNION ALL SELECT emp.`従業員ID`, emp.`姓`、部門`部門ID` FROM従業員 emp RIGHT OUTER JOIN部門部門ON emp.`部門ID` = 部門`部門ID` WHERE emp.`部門ID` IS NULL; # 方法二 SELECT emp.`従業員ID`, emp.`姓`, 部門`部署名` FROM 従業員 従業員 RIGHT OUTER JOIN 部門 部門 ON 従業員ID` = 部門`部門ID` UNION ALL SELECT 従業員ID`, emp.`姓`、部門`部門名` FROM 従業員 emp LEFT OUTER JOIN 部門 dept ON emp.`従業員ID` = 部門`部門ID` WHERE 部門`部門ID` IS NULL;
検索結果:
4.7 7 番目の JOIN
次の操作を実装するには、 4.4 では 4 番目の JOIN を、4.5 では 5 番目の JOIN を見つけるだけで済みます UNION ALL
。
SELECT 従業員ID、従業員姓、部門名 FROM 従業員 従業員 LEFT OUTER JOIN 部門部門 ON 従業員部門ID = 部門ID` WHERE 部門ID` IS NULL UNION ALL SELECT 従業員.`従業員_id`、従業員_姓`、部門_部門名` FROM 従業員 従業員 RIGHT OUTER JOIN 部門部門 ON 従業員_部門ID` = 部門_部門ID` WHERE 従業員_部門ID` IS NULL;
検索結果:
MySQL の内部結合と外部結合、および 7 種類の SQL JOINS の実装に関するこの記事はこれで終わりです。