

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

# JOIN 句
<a name="join-clause"></a>

SQL JOIN 句は、共通のフィールドに基づいて 2 つ以上のテーブルのデータを結合するために使用されます。結果は、指定した結合方法によって変わる場合もあります。左と右の外部結合は、もう一方のテーブルに一致するものが見つからない場合に、結合したどちらかのテーブルの値を保持します。

JOIN タイプと結合条件の組み合わせによって、最終結果セットに含まれる行が決まります。SELECT 句と WHERE 句は、返される列と行のフィルタリング方法を制御します。さまざまな JOIN タイプとそれらを効果的に使用する方法を理解することは、複数のテーブルからのデータを柔軟かつ強力な方法で組み合わせることができるため、SQL の重要なスキルです。

## 構文
<a name="join-clause-syntax"></a>

```
SELECT column1, column2, ..., columnn
FROM table1
join_type table2
ON table1.column = table2.column;
```

## パラメータ
<a name="join-clause-parameters"></a>

 *SELECT column1、column2、...、columnN*   
結果セットに含める列。JOIN に関係するテーブルのいずれかまたは両方から列を選択できます。

 *FROM テーブル 1*   
JOIN オペレーションの最初の (左) テーブル。

 *[JOIN \$1 INNER JOIN \$1 LEFT [OUTER] JOIN \$1 RIGHT [OUTER] JOIN \$1 FULL [OUTER] JOIN] table2: *   
実行する JOIN のタイプ。JOIN または INNER JOIN は、両方のテーブルで一致する値を持つ行のみを返します。  
LEFT [OUTER] JOIN は、左側のテーブルからすべての行を返し、右側のテーブルから一致する行を返します。  
RIGHT [OUTER] JOIN は、右側のテーブルからすべての行を返し、左側のテーブルから一致する行を返します。  
FULL [OUTER] JOIN は、一致があるかどうかにかかわらず、両方のテーブルのすべての行を返します。  
CROSS JOIN は、2 つのテーブルから行のデカルト積を作成します。

 *ON table1.column = table2.column*   
2 つのテーブルの行の一致方法を指定する結合条件。結合条件は、1 つ以上の列に基づくことができます。

 *WHERE 条件: *   
指定された条件に基づいて、結果セットをさらにフィルタリングするために使用できるオプションの句。

## 例
<a name="Join_examples"></a>

次の例は、USING 句が含まれている 2 つのテーブル間の結合です。この場合、listid と eventid の各列が結合列として使用されます。結果は 5 行に制限されます。

```
select listid, listing.sellerid, eventid, listing.dateid, numtickets
from listing join sales
using (listid, eventid)
order by 1
limit 5;

listid | sellerid | eventid | dateid | numtickets
-------+----------+---------+--------+-----------
1      | 36861    | 7872    | 1850   | 10
4      | 8117     | 4337    | 1970   | 8
5      | 1616     | 8647    | 1963   | 4
5      | 1616     | 8647    | 1963   | 4
6      | 47402    | 8240    | 2053   | 18
```

# 結合の種類
<a name="join-types"></a>

## INNER
<a name="inner-join"></a>

これはデフォルトの結合タイプです。両方のテーブル参照で一致する値を持つ行を返します。

INNER JOIN は、SQL で使用される結合の最も一般的なタイプです。これは、共通の列または列のセットに基づいて複数のテーブルのデータを組み合わせる強力な方法です。

**構文:**

```
SELECT column1, column2, ..., columnn
FROM table1
INNER JOIN table2
ON table1.column = table2.column;
```

次のクエリは、顧客と注文テーブルの間に一致する customer\$1id 値があるすべての行を返します。結果セットには、customer\$1id、name、order\$1id、および order\$1date 列が含まれます。

```
SELECT customers.customer_id, customers.name, orders.order_id, orders.order_date
FROM customers
INNER JOIN orders
ON customers.customer_id = orders.customer_id;
```

次のクエリは、LISTING テーブルと SALES テーブル間の内部結合です (JOIN キーワードを除く)。ここで、LISTING テーブルの LISTID は 1～5 です。このクエリは、LISTING テーブル (左のテーブル) と SALES テーブル (右のテーブル) の LISTID 列の値と一致します。結果は、LISTID 1、4、および 5 が基準に一致することを示しています。

```
select listing.listid, sum(pricepaid) as price, sum(commission) as comm
from listing, sales
where listing.listid = sales.listid
and listing.listid between 1 and 5
group by 1
order by 1;

listid | price  |  comm
-------+--------+--------
     1 | 728.00 | 109.20
     4 |  76.00 |  11.40
     5 | 525.00 |  78.75
```

次の例は、ON 句を含む内部結合です。この場合、NULL 行は返されません。

```
select listing.listid, sum(pricepaid) as price, sum(commission) as comm
from sales join listing
on sales.listid=listing.listid and sales.eventid=listing.eventid
where listing.listid between 1 and 5
group by 1
order by 1;

listid | price  |  comm
-------+--------+--------
     1 | 728.00 | 109.20
     4 |  76.00 |  11.40
     5 | 525.00 |  78.75
```

次のクエリは、FROM 句の 2 つのサブクエリを内部結合したものです。このクエリは、イベント (コンサートとショー) の異なるカテゴリのチケットの販売数と売れ残り数を検出します。この FROM 句サブクエリはテーブル**サブクエリです。これらは、複数の列と行を返すことができます。

```
select catgroup1, sold, unsold
from
(select catgroup, sum(qtysold) as sold
from category c, event e, sales s
where c.catid = e.catid and e.eventid = s.eventid
group by catgroup) as a(catgroup1, sold)
join
(select catgroup, sum(numtickets)-sum(qtysold) as unsold
from category c, event e, sales s, listing l
where c.catid = e.catid and e.eventid = s.eventid
and s.listid = l.listid
group by catgroup) as b(catgroup2, unsold)

on a.catgroup1 = b.catgroup2
order by 1;

catgroup1 |  sold  | unsold
----------+--------+--------
Concerts  | 195444 |1067199
Shows     | 149905 | 817736
```

## 左 [外部 ]
<a name="left-outer-join"></a>

左のテーブルリファレンスからすべての値と右のテーブルリファレンスから一致した値を返します。一致しない場合は NULL を追加します。左*外部結合*とも呼ばれます。

左 (1 番目) テーブルのすべての行と右 (2 番目) テーブルの一致する行を返します。右側のテーブルに一致がない場合、結果セットには右側のテーブルの列の NULL 値が含まれます。OUTER キーワードは省略でき、結合は単純に LEFT JOIN として記述できます。LEFT OUTER JOIN の反対は RIGHT OUTER JOIN で、右テーブルのすべての行と左テーブルの一致する行を返します。

**構文:**

```
SELECT column1, column2, ..., columnn
FROM table1
LEFT [OUTER] JOIN table2
ON table1.column = table2.column;
```

次のクエリは、顧客テーブルのすべての行と、注文テーブルの一致する行を返します。顧客が注文がない場合でも、結果セットにはその顧客の情報と order\$1id 列と order\$1date 列の NULL 値が含まれます。

```
SELECT customers.customer_id, customers.name, orders.order_id, orders.order_date
FROM customers
LEFT OUTER JOIN orders
ON customers.customer_id = orders.customer_id;
```

次のクエリは左外部結合です。左と右の外部結合は、もう一方のテーブルに一致するものが見つからない場合に、結合したどちらかのテーブルの値を保持します。左のテーブルと右のテーブルは、構文に一覧表示されている最初と 2 番目のテーブルです。NULL 値は、結果セットの「ギャップ」を埋めるために使われます。このクエリは、LISTING テーブル (左のテーブル) と SALES テーブル (右のテーブル) の LISTID 列の値と一致します。結果は、LISTIDs 2 と 3 が売上につながっていないことを示しています。

```
select listing.listid, sum(pricepaid) as price, sum(commission) as comm
from listing left outer join sales on sales.listid = listing.listid
where listing.listid between 1 and 5
group by 1
order by 1;

listid | price  |  comm
-------+--------+--------
     1 | 728.00 | 109.20
     2 | NULL   | NULL
     3 | NULL   | NULL
     4 |  76.00 |  11.40
     5 | 525.00 |  78.75
```

## 右 [ 外部 ]
<a name="right-outer-join"></a>

右側のテーブルリファレンスからすべての値と左側のテーブルリファレンスから一致した値を返します。一致しない場合は NULL を追加します。*右外部結合*とも呼ばれます。

右 (秒) テーブルのすべての行と、左 (最初の) テーブルの一致する行が返されます。左のテーブルに一致がない場合、結果セットには左のテーブルの列の NULL 値が含まれます。OUTER キーワードは省略でき、結合は単に RIGHT JOIN として記述できます。RIGHT OUTER JOIN の反対は LEFT OUTER JOIN で、左側のテーブルのすべての行と右側のテーブルの一致する行を返します。

**構文:**

```
SELECT column1, column2, ..., columnn
FROM table1
RIGHT [OUTER] JOIN table2
ON table1.column = table2.column;
```

次のクエリは、顧客テーブルのすべての行と、注文テーブルの一致する行を返します。顧客が注文がない場合でも、結果セットにはその顧客の情報と order\$1id 列と order\$1date 列の NULL 値が含まれます。

```
SELECT orders.order_id, orders.order_date, customers.customer_id, customers.name
FROM orders
RIGHT OUTER JOIN customers
ON orders.customer_id = customers.customer_id;
```

次のクエリは右外部結合です。このクエリは、LISTING テーブル (左のテーブル) と SALES テーブル (右のテーブル) の LISTID 列の値と一致します。結果は、LISTID 1、4、および 5 が基準に一致することを示しています。

```
select listing.listid, sum(pricepaid) as price, sum(commission) as comm
from listing right outer join sales on sales.listid = listing.listid
where listing.listid between 1 and 5
group by 1
order by 1;

listid | price  |  comm
-------+--------+--------
     1 | 728.00 | 109.20
     4 |  76.00 |  11.40
     5 | 525.00 |  78.75
```

## FULL [外部]
<a name="full-join"></a>

両方のリレーションからすべての値を返します。一致しない側に NULL 値を追加します。*完全外部結合*とも呼ばれます。

一致するかどうかにかかわらず、左テーブルと右テーブルの両方からすべての行が返されます。一致する行がない場合、結果セットには、一致する行がないテーブルの列の NULL 値が含まれます。OUTER キーワードは省略でき、結合は単に FULL JOIN として記述できます。FULL OUTER JOIN は、LEFT OUTER JOIN や RIGHT OUTER JOIN よりも一般的には使用されませんが、一致するものがない場合でも、両方のテーブルのすべてのデータを表示する必要がある特定のシナリオで役立ちます。

**構文:**

```
SELECT column1, column2, ..., columnn
FROM table1
FULL [OUTER] JOIN table2
ON table1.column = table2.column;
```

次のクエリは、顧客テーブルと注文テーブルの両方のすべての行を返します。顧客が注文がない場合でも、結果セットにはその顧客の情報と order\$1id 列と order\$1date 列の NULL 値が含まれます。注文に関連付けられた顧客がない場合、結果セットにはその注文が含まれ、customer\$1id 列と名前列の値が NULL になります。

```
SELECT customers.customer_id, customers.name, orders.order_id, orders.order_date
FROM customers
FULL OUTER JOIN orders
ON customers.customer_id = orders.customer_id;
```

次のクエリは完全結合です。完全結合は、もう一方のテーブルに一致するものが見つからない場合に、結合したテーブルの値を保持します。左のテーブルと右のテーブルは、構文に一覧表示されている最初と 2 番目のテーブルです。NULL 値は、結果セットの「ギャップ」を埋めるために使われます。このクエリは、LISTING テーブル (左のテーブル) と SALES テーブル (右のテーブル) の LISTID 列の値と一致します。結果は、LISTIDs 2 と 3 が売上につながっていないことを示しています。

```
select listing.listid, sum(pricepaid) as price, sum(commission) as comm
from listing full join sales on sales.listid = listing.listid
where listing.listid between 1 and 5
group by 1
order by 1;

listid | price  |  comm
-------+--------+--------
     1 | 728.00 | 109.20
     2 | NULL   | NULL
     3 | NULL   | NULL
     4 |  76.00 |  11.40
     5 | 525.00 |  78.75
```

次のクエリは完全結合です。このクエリは、LISTING テーブル (左のテーブル) と SALES テーブル (右のテーブル) の LISTID 列の値と一致します。セールスがない行 (LISTID 2 および 3) のみが結果に表示されます。

```
select listing.listid, sum(pricepaid) as price, sum(commission) as comm
from listing full join sales on sales.listid = listing.listid
where listing.listid between 1 and 5
and (listing.listid IS NULL or sales.listid IS NULL)
group by 1
order by 1;

listid | price  |  comm
-------+--------+--------
     2 | NULL   | NULL
     3 | NULL   | NULL
```

## [ 左] セミ
<a name="left-semi-join"></a>

右側と一致するテーブルリファレンスの左側から値を返します。左*半結合*とも呼ばれます。

右 (秒) テーブルに一致する行を持つ左 (最初の) テーブルの行のみを返します。右側のテーブルの列は返されません。左側のテーブルの列のみが返されます。LEFT SEMI JOIN は、2 番目のテーブルからデータを返すことなく、1 つのテーブルで一致する行を別のテーブルで検索する場合に便利です。LEFT SEMI JOIN は、IN 句または EXISTS 句でサブクエリを使用するよりも効率的な方法です。

**構文:**

```
SELECT column1, column2, ..., columnn
FROM table1
LEFT SEMI JOIN table2
ON table1.column = table2.column;
```

次のクエリは、注文テーブルに少なくとも 1 つの注文がある顧客について、顧客テーブルの customer\$1id 列と名前列のみを返します。結果セットには、注文テーブルの列は含まれません。

```
SELECT customers.customer_id, customers.name
FROM customers
LEFT SEMI JOIN orders
ON customers.customer_id = orders.customer_id;
```

## CROSS JOIN
<a name="cross-join"></a>

2 つのリレーションのデカルト積を返します。つまり、結果セットには、条件やフィルターを適用せずに、2 つのテーブルの行の可能な組み合わせがすべて含まれます。

CROSS JOIN は、顧客情報と製品情報の組み合わせをすべて表示するレポートを作成する場合など、2 つのテーブルからデータの組み合わせをすべて生成する必要がある場合に役立ちます。CROSS JOIN は、ON 句に結合条件がないため、他の結合タイプ (INNER JOIN、LEFT JOIN など) とは異なります。結合条件は CROSS JOIN には必要ありません。

**構文:**

```
SELECT column1, column2, ..., columnn
FROM table1
CROSS JOIN table2;
```

次のクエリは、顧客テーブルと製品テーブルからの customer\$1id、customer\$1name、product\$1id、product\$1name の可能なすべての組み合わせを含む結果セットを返します。顧客テーブルに 10 行があり、製品テーブルに 20 行がある場合、CROSS JOIN の結果セットには 10 x 20 = 200 行が含まれます。

```
SELECT customers.customer_id, customers.name, products.product_id, products.product_name
FROM customers
CROSS JOIN products;
```

次のクエリは、LISTING テーブルと SALES テーブルのクロス結合またはデカルト結合で、結果を制限する述語が使用されています。このクエリは、両方のテーブルの LISTID 1、2、3、4、および 5 について、SALES テーブルと LISTING テーブルの LISTID 列の値と一致します。結果は、20 行が基準に一致することを示しています。

```
select sales.listid as sales_listid, listing.listid as listing_listid
from sales cross join listing
where sales.listid between 1 and 5
and listing.listid between 1 and 5
order by 1,2;

sales_listid | listing_listid
-------------+---------------
1            | 1
1            | 2
1            | 3
1            | 4
1            | 5
4            | 1
4            | 2
4            | 3
4            | 4
4            | 5
5            | 1
5            | 1
5            | 2
5            | 2
5            | 3
5            | 3
5            | 4
5            | 4
5            | 5
5            | 5
```

## アンチ結合
<a name="anti-join"></a>

左のテーブルリファレンスから、右のテーブルリファレンスと一致しない値を返します。左*アンチ結合*とも呼ばれます。

ANTI JOIN は、あるテーブルで一致する行を別のテーブルで検索する場合に便利です。

**構文:**

```
SELECT column1, column2, ..., columnn
FROM table1
LEFT ANTI JOIN table2
ON table1.column = table2.column;
```

次のクエリは、注文していないすべての顧客を返します。

```
SELECT customers.customer_id, customers.name
FROM customers
LEFT ANTI JOIN orders
ON customers.customer_id = orders.customer_id
WHERE orders.order_id IS NULL;
```

## NATURAL
<a name="natural-join"></a>

2 つのリレーションの行が、一致する名前を持つすべての列の等価で暗黙的に一致することを指定します。

2 つのテーブル間で同じ名前とデータ型の列が自動的に照合されます。ON 句で結合条件を明示的に指定する必要はありません。2 つのテーブル間の一致するすべての列を結果セットに結合します。

NATURAL JOIN は、結合するテーブルに同じ名前とデータ型の列がある場合に便利です。ただし、一般的には、より明示的な INNER JOIN を使用することをお勧めします。結合条件をより明確でわかりやすいものにする ON 構文。

**構文:**

```
SELECT column1, column2, ..., columnn
FROM table1
NATURAL JOIN table2;
```

次の例は、次の列を持つ `employees`と の `departments`2 つのテーブル間の自然な結合です。
+ `employees` テーブル: `employee_id`、`first_name`、`last_name`、 `department_id `
+ `departments` テーブル: `department_id`、 `department_name `

次のクエリは、`department_id`列に基づいて、2 つのテーブル間で一致するすべての行の名、姓、部門名を含む結果セットを返します。

```
SELECT e.first_name, e.last_name, d.department_name
FROM employees e
NATURAL JOIN departments d;
```

次の例は、2 つのテーブル間の自然結合です。この場合、listid、sellerid、eventid、および dateid の各列は、両方のテーブルで同じ名前とデータ型を持つため、結合列として使用されます。結果は 5 行に制限されます。

```
select listid, sellerid, eventid, dateid, numtickets
from listing natural join sales
order by 1
limit 5;

listid | sellerid  | eventid | dateid | numtickets
-------+-----------+---------+--------+-----------
113    | 29704     | 4699    | 2075   | 22
115    | 39115     | 3513    | 2062   | 14
116    | 43314     | 8675    | 1910   | 28
118    | 6079      | 1611    | 1862   | 9
163    | 24880     | 8253    | 1888   | 14
```