【SQL初心者向け】中学生も理解できるJoin・SubQuery

##はじめに

こんにちは、そして**メリークリスマス:santa_tone2:**！
[Livesense not engineers Advent Calendar 2018](https://qiita.com/advent-calendar/2018/livesense-not-engineers)、最終日を担当いたします。新卒1年目の@harry_aと申します。

今は、転職ナビのユーザーリレーショングループで求職者の皆様一人一人に会う企業の紹介や内定までのサポートを担当しています。

今回はインターン時代からお世話になっていました＠inagakkieさんからお誘いを頂きまして参加させていただきました。
(@inagakkieさん、誘って頂き本当にありがとうございます:bow_tone1:)

もともと入社までは~~経済学部で経営学・マーケティングを必死に勉強~~部活と飲み会の日々を過ごしてきましたし、
入社後は上記のような仕事をしているので、SQLって知ってる？と聞かれた際には
　「“SQL？なにそれ、SNL(Saturday Night Live)的なサムシング？”」的な感じでした。

今日は、こんな私でも理解できた
JoinとSubQuery（サブクエリ）について、簡単な説明と書き方について少しお話しできればと思います。

##1.JOIN

よく使うJOINには大きくINEERとOUTER(LEFT/RIGHT)JOINの２種類がありますが、基本は一緒です。
それは、指定した接続キーを使って違うテーブルを結合することです。

書き方は下記の通りです。
SELECT
　表示したいカラム名
　（もしくは、全て)
FROM
　データベース名.テーブル1名 AS t1 ←のテーブルの略称
　(INNER/LEFT/RIGHT) JOIN 
　　データベース名.テーブル2名 AS t2
　　ON t1.キーカラム名 = t2.キーカラム名
;

```sql
-- 例
SELECT
	coulm1,
	coulm2
	-- もしくは *(全て)

FROM 
	db.tabale1 AS t1
	INNER JOIN 
		db.table2 AS t2
		ON t1.key_coulm_name = t2.key_coulm_name
;
```

#####①INNER JOIN 
INNER JOINは指定した関係性のある要素を軸にした情報のみを表示させます。
例えば、


```sql
SELECT
	t1.number,
	t1.name,
	t2.name
FROM
	db.table1 AS t1
	INNER JOIN
		db.table2 AS t2
		ON t1.number = t2.number
;
```
この場合、結果は、下記のように表示されます。
<img width="790" alt="スクリーンショット 2018-12-25 8.46.53.png" src="https://qiita-image-store.s3.amazonaws.com/0/319839/c1a824e9-a751-632c-887b-4e882e15b23f.png">

#####②OUTER JOIN
OUTER(LEFT/RIGHT)は、FROMで指定した初めのテーブル（左から右へテーブルがくっつくイメージで）に
存在する全てのレコードの情報を表示させます。
LEFTとRIGHTの違いは、基準となるテーブルがFROMで指定した初めのテーブルか、JOINしたテーブルか
ということです。
例えば、LEFT JOINの場合

```sql
SELECT
	t1.number,
	t1.name,
	t2.name
FROM
	db.table1 AS t1
	LEFT JOIN
		db.table2 AS t2
		ON t1.number = t2.number
;
```
結果は下記のように表示されます。
<img width="787" alt="スクリーンショット 2018-12-25 8.55.30.png" src="https://qiita-image-store.s3.amazonaws.com/0/319839/dffcc534-d875-c91f-ba51-c218a21b7ec2.png">

###SQLを使ったデータ分析の際に、知って入れば約立つコツ

####⑴セルフJOIN（自己結合）

名前通り、自己結合。
同じテーブルをもう一度結合する方法です。

例えば、下記のようはテーブルがあるとしましょう。
知りたいのがメンターのチームのである場合、同じテーブルを別名で指定して結合することで

```sql

SELECT 
	t1.team AS 'チーム',
	t1.name AS '名前',
	t1,mentor AS 'メンター名',
	t2,team AS 'メンターのチーム'
FROM 
	db.table1 AS t1
	LEFT JOIN
		db.table1 AS t2
		ON t1.mentor = t2.name
;
```
下記のように表示させることができます。
<img width="966" alt="スクリーンショット 2018-12-25 9.05.28.png" src="https://qiita-image-store.s3.amazonaws.com/0/319839/b165a63b-f64b-d619-f084-8ed2422e2d35.png">

####⑵条件付きJOIN
条件付きJOINは、JOINのON句の次に「AND」句を入れて、改めてフィルターをかける方法です。
例えば、

```sql
SELECT
	*
FROM
	db.table1 AS t1
	LEFT JOIN
		db.table2 AS t2
		ON t1.coulm1 = t2.coulm2
		AND t1.coulm2 = '3'
		-- AND句を使って範囲を指定(書き方はWHEREと一緒です)
;
```
上記のように、JOINの最後にAND+条件を指定して、JOINするテーブルの条件にあった部分のみをJOINできるようになります。

#####そしてセルフJOIN,条件付きJOINを応用すると、下記のように使えたりします。

```sql
-- 同じテーブルの別条件を繰り返しJOINし、内定UU数と、内定承諾UU数を計算します。
SELECT
	COUNT(DISTINCT t2.coulm2) AS '内定UU',
	COUNT(DISTINCT t22.coulm2) AS '内定承諾UU'
FROM
	db.table1 AS t1
	LEFT JOIN
		db.table2 AS t2
		ON t1.coulm1 = t2.coulm2
		AND t1.coulm2 = '3'
	LEFT JOIN 
		db.table2 AS t22
		ON t1.coulm1 = t2.coulm22
		AND t1.coulm2 IN (4,5)
;
```

##2.誰でも1分で理解できるSubQuery

サブクエリを扱い始めると同時に、SQL離脱者が出るという話をよく聞きますが、
SubQueryを書く上で、理解すべきは下記の１つだけだと思います。
**「条件付きで作ったクエリの結果全体を（）に入れて、１つのテーブルもしくは条件として使う」**

例えば、

```sql
SELECT
	COUNT(DISTINCT t2.coulm2) AS '内定UU',
	COUNT(DISTINCT t100.coulm2) AS '承諾売上'
FROM
	db.table1 AS t1
	LEFT JOIN
		db.table2 AS t2
		ON t1.coulm1 = t2.coulm2
		AND t1.coulm2 = '3'
	LEFT JOIN
		(
		SELECT
			coulm2,
			coulm3,
			coulm4,
			coulm6
		FROM
			db.table5
		)AS t100
		ON t2.coulm1 = t100.coulm3
;
```
上記はFROMにおいて、サブクエリを作成し、テーブル代わりで結合しています。

このように「条件付きで作ったクエリの結果全体を（）に入れて、１つのテーブルもしくは条件として使う」ことがSubQueryです。
簡単ですよね？

##終わりに
ここまで、お付き合いありがとうございました。
上記と、基本的な書き方をしっかり抑えて入れば、残りは欲しいデータのありかと接続キーを知るだけなので、
クエリを書くことがますます楽しくなると思います。
私も、宝探しをするようにテーブルのを探検しているうちに、できることが増えてきました。

今年の[Livesense not engineers Advent Calendar 2018](https://qiita.com/advent-calendar/2018/livesense-not-engineers)は本日で終わりますが、
また来年のクリスマスツリーが光る季節になったら戻ってくると思います。是非ともお楽しみにしてください。

そうですね...私は来年、実は本日の記事として書きたかった、GoogleAppScript挑戦記を書きたいと思います。
~~プログラミング言語に触ったことない私ができたのは、SpreadsheetからSlackに「おはよう」を送ることくらいでしたが..~~
それでは、皆様。良いお年を:relaxed:！
<img width="562" alt="スクリーンショット 2018-12-23 20.12.30.png" src="https://qiita-image-store.s3.amazonaws.com/0/319839/8b6c1f69-50ec-78ae-2023-331f8bbb6a13.png">