教材ライブラリ
授業で使うスライド、触って動かせる図解、レッスンの導入スライドをまとめています。 左のリストで絞り込むか、キーワードで検索してください。
5 件 / 全 6 件
SQL入門
WHERE で行を選ぶ
WHERE で行を選ぶ
SELECT が列を選ぶのに対して、WHERE は行を選びます。条件が真になった行だけが結果に残り、偽だった行は捨てられます。
結果
| name | age |
|---|---|
| 佐藤 | 28 |
| 鈴木 | 9 |
| 田中 | 35 |
| 高橋 | 22 |
| 伊藤 | 41 |
取り消し線の2行は条件が偽なので、結果には出てきません。
この >= 25 を動かすと結果が何行になるのかを、次の枚で自分で確かめます。
しきい値で行が減る
n を左右に動かして、残る行の数を見てください。
- n を上げるほど残る行は減る。増えることはない
- n = 0 なら全員が残る。条件が常に真になるから
- n = 42 なら 0 行。空の結果もエラーではなく正しい答え
腕試し (外しても進めます)
age が数値ではなく文字列で入っていたら、age >= '25' に 9 歳は残ると思いますか。
当ててから次の枚で確かめると、答えが記憶に残ります。
文字列として比べると壊れる
トグルを入れて、混ざってくる行を見てください。
- 9 歳が 25 歳以上の側に入る。"9" の先頭が "2" より大きいから
- エラーは出ない。だから気づかないまま本番に出る
- 列の型を数値にしておけば、この事故は起きない
比較演算子の早見
WHERE に書ける条件は等号だけではありません。よく使うものを先に覚えると、あとのレッスンが楽になります。
NULL だけは = で比べられません。NULL は「不明」なので、等しいかどうかも不明になるからです。
| やりたいこと | 書き方 |
|---|---|
| 等しい | = |
| 等しくない | <> または != |
| 大小 | < <= > >= |
| 範囲 | BETWEEN a AND b |
| 集合 | IN (1, 2, 3) |
| NULL 判定 | IS NULL |
SQL入門
INNER JOIN で表をつなぐ
JOIN で2つの表を噛み合わせる
users には注文が入っておらず、orders には名前が入っていません。両方を1つの結果で見るために、どの行とどの行が同じものを指すのかを ON で書きます。
結果
| name | item |
|---|---|
| 佐藤 | 本 |
| 佐藤 | ペン |
| 鈴木 | ノート |
| 鈴木 | 付箋 |
| 田中 | — |
田中 は注文が1件も無いので、結果から消えます。
消えた 田中 を残したいときに LEFT JOIN を使います。このあとの図解で切り替えます。
腕試し (外しても進めます)
users と orders をカンマで並べて FROM に書くと、3行と4行で何行になると思いますか。
当ててから次の枚で確かめると、答えが記憶に残ります。
つなぎ方で結果が変わる
つなぎ方を切り替えて、結果が何行になるか数えてください。
- INNER は相手のいない 田中 が消える
- LEFT は 田中 が残り、item に NULL が入る
- カンマでつなぐと 3 × 4 で 12 行。線が全部と全部に引かれる
つなぎ方の早見
JOIN の種類は「相手がいない行をどうするか」の違いだけです。先に対応を覚えておくと、あとのレッスンで迷いません。
表をカンマで並べると CROSS JOIN と同じ結果になります。JOIN の ON を書き忘れた場合はエラーで止まりますが、カンマはエラーが出ないので、行数が急に増えたら真っ先に疑う場所です。
| やりたいこと | 書き方 |
|---|---|
| 両方にある行だけ | INNER JOIN |
| 左を全部残す | LEFT JOIN |
| 右を全部残す | RIGHT JOIN |
| そろえる条件 | ON a.x = b.y |
| 同じ列名でつなぐ | USING (id) |
| 総当たり | CROSS JOIN |
SQL入門
GROUP BY で束ねて数える
GROUP BY で行を束ねる
WHERE が行を捨てるのに対して、GROUP BY は行を束ねます。同じ値を持つ行がひとかたまりになり、そのかたまりごとに1行が出ます。
結果
| dept | COUNT(*) |
|---|---|
| 営業 | 2 |
| 開発 | 3 |
5行が2行になります。dept の値ごとに1行です。
行が捨てられたのではありません。営業の2行が1行に束ねられただけです。
腕試し (外しても進めます)
GROUP BY dept のあと、SELECT に name を足すとどうなると思いますか。
当ててから次の枚で確かめると、答えが記憶に残ります。
束ねると値が1つに決まる
集計を切り替えたあと、SELECT に name を足してみてください。
- 営業は 30 と 40 の2行が束ねられて1行になる
- AVG に変えると営業は 35。COUNT の 2 とは別の計算
- name を足すと、束ねた行に書ける値が無いのでエラーになる
集計の早見
束ねたかたまりに対して何を計算するかを決めるのが集計関数です。よく使うものと、絞り込みの書き分けを先に押さえます。
WHERE は束ねる前、HAVING は束ねたあとに効きます。「平均が 40 以上の部署だけ」は WHERE では書けません。
| やりたいこと | 書き方 |
|---|---|
| 行数 | COUNT(*) |
| 合計 | SUM(salary) |
| 平均 | AVG(salary) |
| 最大 / 最小 | MAX(salary) / MIN(salary) |
| 束ねる前の絞り込み | WHERE |
| 束ねたあとの絞り込み | HAVING |
SQL入門
NULL の扱い
NULL は値が無いのではなく不明
NULL は空文字でも 0 でもありません。「分からない」という状態です。分からない値と何かを比べても、答えはやはり分かりません。
結果
| name | |
|---|---|
| 佐藤 | a@example.com |
| 鈴木 | NULL |
| 田中 | b@example.com |
| 加藤 | NULL |
1行も返りません。エラーも出ません。
= NULL は必ず 0 行になります。NULL の行すら返らないのが、いちばん引っかかる点です。
腕試し (外しても進めます)
WHERE email != 'a@example.com' は、この4行のうち何行を返すと思いますか。
当ててから次の枚で確かめると、答えが記憶に残ります。
真でも偽でもない
条件を切り替えて、返る行数がどう変わるか見てください。
- = NULL は 0 行。IS NULL なら 鈴木 と 加藤 の2行
- != でも NULL の行は返らない。「違う」も判定できない
- 真・偽のほかに「不明」がある、と考えると筋が通る
NULL の扱い早見
比較演算子は NULL に効きません。NULL を相手にするときは、専用の書き方に切り替えます。
この4行なら COUNT(*) は 4、COUNT(email) は 2 になります。COUNT が2種類あるのではなく、集計関数が NULL を数えないからです。
| やりたいこと | 書き方 |
|---|---|
| NULL かどうか | IS NULL |
| NULL でないか | IS NOT NULL |
| NULL を別の値に | COALESCE(email, '未登録') |
| NULL を数えない | COUNT(email) |
| 全行を数える | COUNT(*) |
SQL入門
索引 (インデックス) はなぜ速いのか
索引は全部めくらずに飛ぶ
索引が無いと、データベースは先頭から順に読み、最悪は全行を読みます。索引は本の巻末の索引と同じで、読む場所へ直接飛べるようにする仕組みです。
調べる回数
| 行数 | 索引なし | 索引あり |
|---|---|---|
| 100 | 100 | 7 |
| 10,000 | 10,000 | 14 |
| 1,000,000 | 1,000,000 | 20 |
行数が1万倍になっても、索引ありは3倍にしかなりません。
この差は行数が増えるほど開きます。100行では体感できないので、小さい表で試すと効果が分かりません。
腕試し (外しても進めます)
索引を増やすと、書き込みの速さはどうなると思いますか。
当ててから次の枚で確かめると、答えが記憶に残ります。
検索は速く、書き込みは遅く
行数を増やしたあと、書き込みに切り替えてみてください。
- 検索は行数を増やすほど差が開く。索引ありの棒はほとんど伸びない
- 書き込みに切り替えると逆転する。索引ありのほうが遅い
- だから「とりあえず全部の列に張る」は間違い
張る列・張らない列
索引は速くする道具ではなく、検索と書き込みを取り引きする道具です。どちらが多い表なのかで判断します。
値の種類が少ない列に張っても効きません。男女2種類しか無い列の索引は、結局半分の行を読むことになるからです。
| どんな列・表か | 索引 |
|---|---|
| WHERE で毎回使う列 | 張る |
| JOIN の ON に出る列 | 張る |
| ORDER BY で並べる列 | 張る |
| 値の種類が少ない列 | 張らない |
| 書き込みが多い表 | 張らない |
| 行数が少ない表 | 張らない |