【SQL Server】結合(JOIN)についての学習

# 「結合」について
複数のテーブルやビューを組み合わせて、データをまとめて扱えるようにする事を「結合」と呼びます。
結合には、いくつかの種類があります。
私の業務では扱う事がないのですが、基礎的な事なので覚えておきます。


## クロス結合について
対象テーブルに存在するレコードを全て結合する方法をクロス結合と言います。
レコード数 × レコード数　分のデータを取得出来ます。

構文は、`SELECT * FROM 結合対象テーブルA CROSS JOIN 結合対象テーブルB`となります。

実際にやってみようと思います。
テストデータとして、Test_01テーブルとTest_02テーブルを作成します。

```:Test_01
CREATE TABLE Test_01(

	code INT PRIMARY KEY,
	name VARCHAR(40),
	level INT,

);	

INSERT INTO Test_01 (code,name,level) VALUES (1,'ウィング・エッグ・エルフ',3);
INSERT INTO Test_01 (code,name,level) VALUES (2,'カース・オブ・ドラゴン',5);
INSERT INTO Test_01 (code,name,level) VALUES (3,'岩石の巨兵',3);
```

```:Test_02
CREATE TABLE Test_02(
	code INT PRIMARY KEY,
	type VARCHAR(40),
);

INSERT INTO Test_02(code,type) VALUES (1,'Normal');
INSERT INTO Test_02(code,type) VALUES (2,'Effect');
```

テーブルの中身は、以下のような感じです。

`SELECT * FROM Test_01`
`SELECT * FROM Test_02`
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710307/34bb2d97-7600-8186-a714-e29e76afa69f.png)

結合させてみます。
`SELECT * FROM Test_01 CROSS JOIN Test_02;`
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710307/5facad7b-b30b-a545-d0c7-613692bdeaba.png)

結合出来ました。Test_01のレコード数(3) × Test_01のレコード数(2)　で６レコードのデータが作成されている事を確認致しました。 
しかし、使い所がぱっと思いつかないです。

## 内部結合について
対象テーブル内で指定した列の値が一致するデータを取得する方法を内部結合と言います。
列の指定はONで行います。

構文は、`SELECT * FROM 結合対象テーブルA INNER JOIN 結合対象テーブルB ON カラム名 = カラム名`となります。

実際にやってみます。
テストデータとして、Test_03テーブルを作成します。

```:Test_03
CREATE TABLE Test_03(
	code INT PRIMARY KEY,
	attack INT,
	defense INT
);

INSERT INTO Test_03 VALUES(1,500,1300)
INSERT INTO Test_03 VALUES(3,1300,2000)
```

テーブルの中身は、以下のような感じです。

`SELECT * FROM Test_03`
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710307/229e4502-3b57-0a99-0559-fc4fced02b03.png)



結合させてみます。
`SELECT * FROM Test_01 INNER JOIN Test_03 ON Test_01.code = Test_03.code`
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710307/44f338e6-9278-67f3-2135-f424c9d9e9b3.png)

Test_01/Test_03テーブル内で、codeが一致するデータのみが表示されました。
Test_03テーブルにcode：2に該当するデータが存在しない為に、Test_01テーブルに存在するcode:2のデータは取得されていない事を確認しました。

## 左外部結合/右外部結合について
左側のテーブル/右側のテーブルのいずれかを基準にして、テーブルの結合を行います。
列の指定はONで行います。
左外部結合だと、左側のテーブルは全てのデータが取得されますが、右側のテーブルはONで指定した条件に一致するデータが取得されます。
左側のテーブルにデータ有/右側のテーブルにデータ無の場合は、右側のテーブルのレコードにはNULL値が入ります。右外部結合は基準となるテーブルが単純に右となります。

構文は、`SELECT * FROM 結合対象テーブルA LEFT Or RIGHT JOIN 結合対象テーブルB ON カラム名 = カラム名`となります。

実際に結合してみます。
`SELECT * FROM Test_01 LEFT JOIN Test_03 ON Test_01.code = Test_03.code`
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710307/c7398ebd-223f-bb8a-a9d2-48c2b4573dcd.png)

`SELECT * FROM Test_03 RIGHT JOIN Test_01 ON Test_01.code = Test_03.code`
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710307/f6627835-492b-ddee-a58f-02bf2258dd0f.png)

LEFTとRIGHTは使い分けているのでしょうか？
実務で使う事がないので、不明です。個人学習では、RIGHTを使った事がないです。

## 全外部結合について
全外部結合では、値の一致に関わらず、データの取得は行います。テーブルにデータが存在していない場合は、NULL値が入ります。

構文は、`SELECT * FROM 結合対象テーブルA FULL JOIN 結合対象テーブルB ON カラム名 = カラム名`となります。

動作を分かりやすく観測したい為に、Test_03テーブルに少しデータを増やします。

```:データ投入
INSERT INTO Test_03 (code,attack,defense) VALUES (4,1600,1200);
```


`SELECT * FROM Test_01 FULL JOIN Test_03 ON Test_01.code = Test_03.code`
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710307/252b7e80-f4b9-49eb-fef4-5f71a330f39a.png)


データ取得が行えました。存在していないデータはNULL値になっている事も確認出来ました。

## 終わり
結合は業務で使った事がなかったですが、業務上の会話では結構出てくるので色々と知れて良かったです。
個人学習では、左外部結合と全外部結合は今後も使っていけそうです。