「オンラインハンズオン はじめてのSQL」(勉強会レポート) 

### はじめに 
この記事は, 現役エンジニアの[どいこさん](https://twitter.com/doiko_niki)が主催された勉強会「オンラインハンズオン はじめてのSQL」のレポート記事になります。

![Screen Shot 2021-04-11 at 2.45.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482077/be78522e-b44d-8b7d-73db-4abee860c808.png)

　この記事では、勉強会の中でも特にタメになった「間違ったSQL文を正しく直す」という練習問題をピックアップしてまとめたいと思います！ この記事を読んで,ご自身のSQLの理解度をチェックされてみても良いと思います！ また勉強会では,実務でSQLを使う際のとても興味深い小話もしていただいたので、そちらも最後にオマケとして書かせていただきます!

※この記事の対象者は,「はじめてSQLを触る人」なので初心者の方もお読みいただくことができます！ 初心者大歓迎！

![text_syoshinsya_kangei.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482077/9473d1e2-abe9-4d25-c2c5-d3d58ddf991f.png)

### 目次 
1. このINSERT文の間違いは何？
2. 論理演算子NOT,AND,ORはどの順番で実行される？
3. 実務ではどんなSQLを書くの？

### 1. このINSERT文の間違いは何？
 突然ですが問題です！ 

####(問)
どいこさんが経営する食堂では春に新メニュー「天津チャーハン餃子唐揚げ焼き小籠包定食」を新たに追加したいと考えています。どいこさんはINSERT文を使ってメニューのデータベースに新作メニューを追加しようとしましたが、上手く追加できません。SQL文を修正して, 春の新作メニューを追加してください。使用するDBMSはPostgreSQLになります。

![img_404afecb9653c844ea0e03491345af6c218741.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482077/bfe7a6a6-e0e3-9b39-f818-62c1ded9022e.jpeg)

・メニューのデータベース

| id | category | name | price |
|:-: |:-:       |:-:   |:-:    |
|  1 | 定食  |  焼きそば定食 | 800  |
|  2 |  単品 |  カレーライス |  600 |
|  3 |  単品 |  うどん |  500 |

・追加したいデータの詳細
名前「天津チャーハン餃子唐揚げ焼き小籠包定食」
カテゴリー「定食」
値段「980円」

・どいこさんが書いたSQL

```
INSERT INTO menus
 ("id", "category", "name", "price")
VALUES
 ('12', '980', '天津チャーハン餃子唐揚げ焼き小籠包定食')
```

・エラー文の内容
`Help: 42601 INSERT has more target columns than expressions`

以下は解説になります
.
.
.
.
.
・
#### 解説
まずは, INSERT文の文法から確認しましょう！

```
INSERT INTO テーブル名 (列1, 列2, 列3) 
VALUES (値1, 値2, 値2)
```
ポイントは,指定した列の順番と追加したい値の順序が一致していることです。例えば、列1には値1が代入されます。

参考 : [PostgreSQL公式ドキュメント(日本語)](https://www.postgresql.jp/document/9.4/html/dml-insert.html)

それを踏まえて, エラー文の内容を確認すると

`Help: 42601 INSERT has more target columns than expressions`

英語が少し難しく感じるかもしれませんが、訳すと「INSERTは記述されている(VALUEの)数より多くの列を指定してますよ！」と書かれています。どういうことでしょうか？ どいこさんが書いたSQLをもう一度見てみましょう。

```
INSERT INTO menus
 ("id", "category", "name", "price")
VALUES
 ('12', '980', '天津チャーハン餃子唐揚げ焼き小籠包定食')
```

ふむふむ、、id,category,name,priceと指定した列が4つなのに対して、列に入れたい値が3しかありませんね。それに加えて, カテゴリーの列に980円の数字が対応しているミスもあります。この２つを改善するとコードは以下の通りになります。

(追加)元々の資料ではidとpriceが数値型で指定されていたので、シングルクォート''を外す必要もありました。ご指摘いただきありがとうございます！

```
INSERT INTO menus
 ("id", "category", "name", "price")
VALUES
 (12, '定食', '天津チャーハン餃子唐揚げ焼き小籠包定食',980)
```

理解できましたか？ポイントは、`値を入れたい列と値の順番が対応していること`になります。解けなかった人は[PostgreSQL公式ドキュメント(日本語)](https://www.postgresql.jp/document/9.4/html/dml-insert.html)で文法を再確認しておきましょう！

### 2. 論理演算子NOT,AND,ORはどの順番で実行される？

#### (問)
今日のどいこさんは,とにかく腹ペコです。

![d15879e64d14c05a307f8430a7598e80.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482077/7a2c3ab0-dee2-fb97-554b-3272449ee489.jpeg)
定食でも単品でもいいから,お米か揚げ物のメニューをガッツリ食べたい気分だったようで、SQLを使ってそのようなメニューを検索しようと以下のSQL文を書きました。

```
SELECT category, name, price FROM menus
WHERE category = '定食' or category = '単品' 
AND name LIKE ('%ライス%') OR name LIKE ('%フライ%')
```

しかし,このSQL文を実行してみると「定食のメニュー、単品で名前にライスと入っているメニュー、名前にフライと入っているメニュー」が出てきました。揚げ物か米が食べたいのに、関係のない定食が出てきたので、どいこさんはプンプンです。(# ﾟДﾟ)

どいこさんのために、正しいSQL文を書いてあげてください。

#### 解説
まず,抑えるべきポイントは`論理演算子NOT,AND,ORの実行順序`です。SQLではNOT,AND,ORの順番に処理が実行されます。「??」ってなってますか？実際にどいこさんの書いたSQLで確認してみましょう。

```
SELECT category, name, price FROM menus
WHERE category = '定食' or category = '単品' 
AND name LIKE ('%ライス%') OR name LIKE ('%フライ%')
```

実行順序は`NOT,AND,OR`です。なのでまず`category = '単品' 
AND name LIKE ('%ライス%')`が1つのまとまった処理として実行されます。その後, or句で書かれた3つの処理が以下のように前から順番で実行されます。

```
category = '定食'
or
category = '単品' AND name LIKE ('%ライス%')
or
「name LIKE ('%フライ%')
```

正解は,実行したいまとまりを()でくくってあげるとうまくいきます。

```
SELECT category, name, price FROM menus
WHERE 
( category = '定食' or category = '単品' ) 
AND 
( name LIKE ('%ライス%') OR name LIKE ('%フライ%'))
```

こうすると, 「定食か単品」 かつ 「ライスかフライ」としてwhere句が処理されます。

解けましたか？

### 3. 実務ではどんなSQLを書くの？
 どいこさんやXhackの社員さんに「実務ではどんなSQLを書くのですか？」という質問をしてみたところ、面白い答えを返していただいたのでそれをお伝えします。

Xhackの松田さんはエグい量のSQL文を書いたことがあるそうです。

どれくらいでしょうか？
・
・
・
・
なんと500行です！ エグすぎ！笑 

初心者が,数百行ものSQLを書く機会はそうそうに無いと思いますが、実際の業務ではそんなこともあるんですね、、、、

ほかにも,なぜエクセルではなくデータベースを使うのか？ということもお話されていました。

皆さんは普段エクセルを扱う時どれくらいの行数のデータを扱っていたか覚えていますか？ せいぜい数100行だと思います。それでもエクセルファイルを開くときは少々重いなぁといったところでしょうか。 一方で、実務のシステムでは,10億行ものデータを扱うこともあるそうです！ とてつもない量ですね、、、このような膨大な量のデータを扱う場合はエクセルでは到底開けないそうです。そのため、データ処理に特化したデータベースシステムで扱うことになるそうです。

#### おわりに
　この勉強会ではSQLを実際にオンラインで手を動かしながら学ぶことが出来てとても勉強になりました！他にも, 現役のエンジニアの方からSQLが現場でどのように使われているのか？といったとても興味深いお話も聞くことが出来ました！ 主催してくださった どいこさん並びにXhackの松田さん、ありがとうございます！

### 参考 
・[SQL勉強会の資料](https://www.notion.so/SQL-d77c1e82cb5b4e19962fd54727189f6d)
・[posgresql公式ドキュメント](https://www.postgresql.jp/document/9.4/html/dml-insert.html)
・[SQLite Online(オンラインでSQLを試しに実行できる便利なツールです)](https://sqliteonline.com/)
・[スッキリわかるSQL入門 第２版 ドリル222門付き！](https://www.amazon.co.jp/-/en/gp/slredirect/picassoRedirect.html/ref=pa_sp_atf_aps_sr_pg1_1?ie=UTF8&adId=A1BYHOWHPM877N&url=%2F%25E4%25B8%25AD%25E5%25B1%25B1%25E6%25B8%2585%25E5%2596%25AC%2Fdp%2F4295005096%2Fref%3Dsr_1_1_sspa%3Fdchild%3D1%26keywords%3Dsql%26qid%3D1618071077%26sr%3D8-1-spons%26psc%3D1&qualifier=1618071077&id=319539839996612&widgetName=sp_atf)