【非エンジニア・初心者向け】SQL入門 & 20本ノック

# はじめに
こんにちは。
[Matcher株式会社](https://www.wantedly.com/companies/matcher#_=_)でエンジニアをしている者です。

元々 Matcher 社内で非エンジニア・初心者向けに
SQL の勉強会をする為に作るつもりだったのですが、
せっかく作るので公開できる形にしました。

# こんな人向けです
・全く SQL をやったことがないけどやりたい！
・非エンジニアだけどデータ分析の為に SQL をやる必要が出てきた！
・データサイエンティストにちょい興味あるけど何から始めたらよい？
・「ビジネス職で SQL 自分で叩けるなんて...！」と社内でモテモテになりたい！

# やること
① Progate (無料の範囲で)
② オリジナル SQL 20本ノック (入門者向け)
③『入門 → 初中級』に向けた演習 (おすすめ外部サイト)

※ 前提 ※
SQL をできるようになる為には何よりも
『実際に手を動かしてたくさん SQL をたたく』
ことが重要だと考えているので、演習中心の内容です。


## ① Progate (無料の範囲で)
Progate
→ https://prog-8.com/courses/sql

[<img width = 500 src = "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/210717/92701356-4b60-d5fb-412e-e6ebfe6d762f.png">](https://prog-8.com/courses/sql)

『SQL I』は無料でできます。
ここで基本的な内容をさらいます。

※ 有料会員の方は Progate を進めるだけでもかなり勉強できると思うので
一旦 Progate 全てを終わらせることをおすすめします。

## ② オリジナル SQL 20本ノック
②は『① Progate』をやっている前提の内容です。
まだ①をやっていない方はそちらから。

分からないことが出てきた場合はProgateを見直すも良いですが、
できればまずはググってみましょう。

例えば
『sql select 使い方』
『sql where 使い方』
『sql 大きい順 並び替え』
等調べればたくさんの情報が出てきます。

分からないことを調べて、理解して、利用・応用することができるようになれば
怖いものはありません。

### 1. [SQL Fiddle](http://sqlfiddle.com/#!9/4191fb) にアクセス
→ http://sqlfiddle.com/#!9/4191fb

※ もしアクセスしても画面左のスペースに何も表示されていなかったら
下記コードをコピーして画面左のスペースに貼り付け。
→ [Build Schema] ボタンをクリック！

```sql
CREATE TABLE fruits
    (`id` int, `name` varchar(8), `price` int, `production_area` varchar(3), `season` varchar(1))
;
    
INSERT INTO fruits
    (`id`, `name`, `price`, `production_area`, `season`)
VALUES
    (1, 'りんご', 100, '青森', '秋'),
    (2, 'みかん', 80, '和歌山', '冬'),
    (3, 'りんご', 120, '長野', '秋'),
    (4, 'デコポン', 180, '熊本', '春'),
    (5, 'ぶどう', 300, '山梨', '秋'),
    (6, 'スイカ', 1000, '熊本', '夏'),
    (7, '桃', 300, '山梨', '夏'),
    (8, '梨', 150, '千葉', '秋'),
    (9, '柿', 130, '和歌山', '秋'),
    (10, 'いちご', 400, '栃木', '冬'),
    (11, 'グレープフルーツ', 130, '静岡', '春'),
    (12, 'りんご', 120, '長野', '秋'),
    (13, 'ぶどう', 280, '長野', '秋'),
    (14, 'みかん', 100, '愛媛', '冬')
;

```


### 2. 問題を解く
なんとなく難易度順に並べたつもりですが基本はてきとうです。
とにかく手を動かしてたくさん解いていきます。

回答例も下の方に載せてあるので必要があれば参考にしてください。
基本的に正解はひとつではなく、
目的のアウトプットが出ていれば問題ないです。

(もちろん、キレイな書き方というものは存在しますが
それを最初から意識する必要はないと個人的には考えています。)

#### 2-1
【**fruits テーブルの全カラムからデータを取得**】

↓アウトプットイメージ
<img width="500" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/210717/7d43ca9c-746a-e6fc-fb58-a0e77ef141c9.png">


#### 2-2
【**fruits テーブルの『name』『production_area』カラムのデータを取得**】

↓アウトプットイメージ
<img width="500" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/210717/75ca9c74-9358-0b98-7099-d6b85c17ae9e.png">


#### 2-3
【**fruits テーブルの全カラムからデータを取得し、カラム名を画像のような形で表示**】

↓アウトプットイメージ
<img width="500" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/210717/6e6a6aec-176d-bc40-d0c4-03eefd47ba2b.png">


#### 2-4
【**旬の季節が夏のくだもののみ取得**】

↓アウトプットイメージ
<img width="500" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/210717/4e138217-1403-1830-7461-55e08ff839bd.png">


#### 2-5
【**価格が200円以下のもののみ取得**】

↓アウトプットイメージ
<img width="500" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/210717/f8d68740-abff-a9b7-3107-8148c7e6a5cc.png">


#### 2-6
【**価格が300円以上のもののみ取得**】

↓アウトプットイメージ
<img width="500" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/210717/40d8641c-c904-1b2d-ccc3-45eb0667873e.png">


#### 2-7
【**価格が高い順に表示**】

↓アウトプットイメージ
<img width="500" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/210717/c0f6adae-1a55-cdf0-adb5-d1eec9b19bb9.png">


#### 2-8
【**価格が低い順に3つだけ表示**】

↓アウトプットイメージ
<img width="500" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/210717/227a6edf-a8c9-319b-893a-3ec3f20a03b9.png">


#### 2-9
【**価格が500円以下 & 旬の季節が夏**】

↓アウトプットイメージ
<img width="500" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/210717/94bf9396-1a4a-88f7-98a7-effd6715d538.png">


#### 2-10
【**価格が250円以上 & 旬の季節が秋**】

↓アウトプットイメージ
<img width="500" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/210717/2138d365-02b5-68b4-f9aa-6a575a241888.png">


#### 2-11
【**旬の季節が夏 or 秋のくだもの**】

↓アウトプットイメージ
<img width="500" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/210717/36769472-7a35-d5ff-94c5-87870cd272f4.png">


#### 2-12
【**旬の季節が冬のくだものを価格が高い順に表示**】

↓アウトプットイメージ
<img width="500" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/210717/7a07d15d-c9c3-133e-8cf1-7cd16bbb67b1.png">


#### 2-13
【**りんごの中で最も価格が安いもの**】

↓アウトプットイメージ
<img width="500" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/210717/4d895c34-f22c-9070-dc6a-2ab415b173d0.png">


#### 2-14
【**旬の季節が秋 or 冬のくだものを価格が高い順に5つ表示**】

↓アウトプットイメージ
<img width="500" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/210717/5b35eb60-e97f-178c-e251-136b49d485bd.png">


#### 2-15
【**くだものの種類を"重複無し"で表示**】

Progate の『SQL I』には含まれていない内容です。
必要があれば調べて実装してみましょう。

例)
『sql 重複なし』

↓アウトプットイメージ
<img width="500" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/210717/ece4ed95-ef6c-0c52-d01d-586a4865e713.png">


#### 2-16
【**山梨県産のくだものの種類**】

Progate の『SQL I』には含まれていない内容です。
必要があれば調べて実装してみましょう。

例)
『sql カウント 条件』
『sql 集計関数』

↓アウトプットイメージ
<img width="500" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/210717/8b20614b-2be2-e695-fff7-f9ccad41b323.png">


#### 2-17
【**旬の季節が冬のくだものの合計価格**】

Progate の『SQL I』には含まれていない内容です。
必要があれば調べて実装してみましょう。

例)
『sql 合計』
『sql 集計関数』

↓アウトプットイメージ
<img width="500" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/210717/7b48cc50-c8b3-1f2c-d031-509d665e3101.png">


#### 2-18
【**全てのくだものの [最大価格] [最小価格]**】

Progate の『SQL I』には含まれていない内容です。
必要があれば調べて実装してみましょう。

例)
『sql 最大値 最小値』

↓アウトプットイメージ
<img width="500" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/210717/abea66bd-8708-833b-8870-1f981be3539e.png">


#### 2-19
【**各季節のくだものの [最大価格] [最小価格] [その価格差]**】

Progate の『SQL I』には含まれていない内容です。
必要があれば調べて実装してみましょう。

例)
『sql 最大値 最小値』
『sql 四則演算』
『sql グループ分け』


↓アウトプットイメージ
<img width="500" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/210717/a28aea11-ad1d-92ac-9da9-885ba0c253ea.png">


#### 2-20
【**各産地のくだものの種類 (重複なし)**】

Progate の『SQL I』には含まれていない内容です。
必要があれば調べて実装してみましょう。

例)
『sql 重複無し カウント』
『sql グループごとにカウント』

↓アウトプットイメージ
<img width="500" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/210717/b1879767-8c05-e164-4610-62e2a164e3ae.png">

## ③ 『入門 → 初中級』 に向けた演習問題
### 1. [SQL練習問題 一覧まとめ](https://tech.pjin.jp/blog/2016/12/05/sql練習問題-一覧まとめ/)
→ https://tech.pjin.jp/blog/2016/12/05/sql練習問題-一覧まとめ/

**・SQL入門練習問題シリーズ**
**・基礎力チェックシリーズ**
**・力試しシリーズ**
と3つ用意されており、問題数も豊富で解答解説までついている非常に神なサイトです。

しかし、②の20本ノックで使用していた SQL Fiddle とは違い
PC 側で少し準備 ( MySQL の環境構築) が必要です。

=== === === === === === === === === ===
▶︎ Windows の場合 : https://prog-8.com/docs/mysql-env-win
▶︎ Mac の場合 : https://prog-8.com/docs/mysql-env
=== === === === === === === === === ===
↑ こちらを参考に MySQL の環境構築をしましょう。

※ もし記事通りに行ってもできない場合は
・出てきたエラーでググる
・『myspl windows 環境構築』等でググる
などして、なんとかしましょう。

前述の記事通りの方法でなくても MySQL が使える環境が整えば
どんな方法でも構いません。


### 2. [MySQL10本ノック作ってみた！](https://qiita.com/yasumon/items/a11b0e5d93e9bebec7a2)

→ https://qiita.com/yasumon/items/a11b0e5d93e9bebec7a2

問題と、しっかり解答解説も用意してくれています。
問題を解くための環境も1と同様の環境でできます。


### 3. [データサイエンス100本ノック (構造データ加工編)](https://github.com/The-Japan-DataScientist-Society/100knocks-preprocess)

→ https://github.com/The-Japan-DataScientist-Society/100knocks-preprocess

『データサイエンス100本ノック』といういかにもな名前のやつです。
実際に取り掛かる際にはこちらの記事が参考になりそうです。

=== === === === === === === === === ===
データサイエンス100本ノックをやってみた【その１：SQL編】
→ https://meow3571.hateblo.jp/entry/2020/06/28/195835
=== === === === === === === === === ===

筆者もこちらは現在未実施の為、
実際にやってみた後に環境構築方法等を追記します。

先に100本ノックにチャレンジした多くの方々が記事等上げて下さっているので
分からなくなった際にも頼ることのできる資料は多そうです。

例)
▶︎ [データサイエンス100本ノック(構造化データ編)SQL版全問題解説](https://festakebab.hatenadiary.com/entry/2020/07/08/091220)
▶︎[【SQL編】データサイエンス100本ノック解説【1~20】](https://qiita.com/Strix9289/items/9dfe4c911f6c206ff215)
▶︎[【SQL編】データサイエンス100本ノック【21~40】](https://qiita.com/Strix9289/items/a7b813ade174ebb27409)
▶︎[【SQL編】データサイエンス100本ノック解説【41~60】](https://qiita.com/Strix9289/items/0d0023de3c28c3244529)
▶︎[【SQL編】データサイエンス100本ノック解説[61~80]](https://qiita.com/Strix9289/items/846a430d0885373898fb)

ここまで完遂できればかなり力がついていそうです。

その他、SQLの勉強に役立つ教材やサイト等ご存知の方がいらっしゃいましたら
コメント等で教えていただけると幸いです。


## ※ 20本ノックの回答例
#### 2-1
```sql
select * from fruits;
```

#### 2-2
```sql
select name, production_area
from fruits;
```

#### 2-3
```sql
select
  id
  , name as `名前`
  , price as `価格`
  , production_area as `産地`
  , season as `旬の季節`
from fruits
;
```
※ 上記のような形で見やすい位置で改行を入れたりして書いてもOK。

#### 2-4
```sql
select
  id
  , name as `名前`
  , price as `価格`
  , production_area as `産地`
  , season as `旬の季節`
from fruits
where season = "夏"
;
```

#### 2-5
```sql
select
  id
  , name as `名前`
  , price as `価格`
  , production_area as `産地`
  , season as `旬の季節`
from fruits
where price <= 200
;
```

#### 2-6
```sql
select
  id
  , name as `名前`
  , price as `価格`
  , production_area as `産地`
  , season as `旬の季節`
from fruits
where price >= 300
;
```

#### 2-7
```sql
select
  id
  , name as `名前`
  , price as `価格`
  , production_area as `産地`
  , season as `旬の季節`
from fruits
order by price desc
;
```

#### 2-8
```sql
select
  id
  , name as `名前`
  , price as `価格`
  , production_area as `産地`
  , season as `旬の季節`
from fruits
order by price asc
limit 3
;
```

#### 2-9
```sql
select
  id
  , name as `名前`
  , price as `価格`
  , production_area as `産地`
  , season as `旬の季節`
from fruits
where price <= 500
and season = "夏"
;
```

#### 2-10
```sql
select
  id
  , name as `名前`
  , price as `価格`
  , production_area as `産地`
  , season as `旬の季節`
from fruits
where price >= 250
and season = "秋"
;
```

#### 2-11
```sql
select
  id
  , name as `名前`
  , price as `価格`
  , production_area as `産地`
  , season as `旬の季節`
from fruits
where season = "夏"
or season = "秋"
;
```
```sql
select
  id
  , name as `名前`
  , price as `価格`
  , production_area as `産地`
  , season as `旬の季節`
from fruits
where season in ("夏", "秋")
;
```
どちらでも可。

#### 2-12
```sql
select
  id
  , name as `名前`
  , price as `価格`
  , production_area as `産地`
  , season as `旬の季節`
from fruits
where season = "冬"
order by price desc
;
```

#### 2-13
```sql
select
  id
  , name as `名前`
  , price as `価格`
  , production_area as `産地`
  , season as `旬の季節`
from fruits
where name = "りんご"
order by price asc
limit 1
;
```

#### 2-14
```sql
select
  id
  , name as `名前`
  , price as `価格`
  , production_area as `産地`
  , season as `旬の季節`
from fruits
where season = "秋"
or season = "冬"
order by price desc
limit 5
;
```
```sql
select
  id
  , name as `名前`
  , price as `価格`
  , production_area as `産地`
  , season as `旬の季節`
from fruits
where season in ("秋", "冬")
order by price desc
limit 5
;
```
どちらでも可。

#### 2-15
```sql
select distinct 
  name as `名前`
from fruits
;
```

#### 2-16
```sql
select
  count(*) as `山梨県産のくだものの種類`
from fruits
where production_area = "山梨"
;
```

#### 2-17
```sql
select 
  sum(price) as `旬の季節が冬のくだものの合計価格`
from fruits
where season = "冬"
;
```

#### 2-18
```sql
select 
  max(price) as `最大価格`
  , min(price) as `最小価格`
from fruits
;
```

#### 2-19
```sql
select 
  season as `旬の季節` 
  , max(price) as `最大価格`
  , min(price) as `最小価格`
  , max(price) - min(price) as `価格差`
from fruits
group by season
;
```

#### 2-20
```sql
select 
  production_area as `産地`  
  , count(distinct name) as `各産地のくだものの種類`
from fruits
group by production_area
;
```