はじまり
人間さん「う~ん…」
いぬ先生「どうしたの?」
人間さん「果物を仕入れて管理してるんだけど」
人間さん「これを見てほしい」
products テーブル
| id | name | condition | price |
|---|---|---|---|
| 1 | りんご | 良 | 20 |
| 2 | オレンジ | 悪 | 200 |
| 3 | りんご | 悪 | 2000 |
| 4 | もも | 良 | 100 |
| 5 | オレンジ | 良 | 500 |
人間さん「だれよ?状態悪いりんごを2000円にしたの…」
人間さん「あと良いりんごも20円って安すぎよ…」
いぬ先生「間違いなく入力ミスってるね~」
SELECTで使う
人間さん「ちょいとリストに出すか」
人間さん「SELECTとSELECTをUNIONで繋げて…」
人間さん「よしできた」
SELECT
id,
name,
condition,
price AS '元価格',
300 AS '新価格'
FROM
products
WHERE
name = 'りんご',
AND condition = '良'
UNION
SELECT
id,
name,
condition,
price AS '元価格',
100 AS '新価格'
FROM
products
WHERE
name = 'りんご',
AND condition = '悪';
人間さん「実行っと」
| id | name | condition | 元価格 | 新価格 |
|---|---|---|---|---|
| 1 | りんご | 良 | 20 | 300 |
| 3 | りんご | 悪 | 2000 | 100 |
人間さん「うん、この値段設定でいくか」
いぬ先生「ちょっと待って」
人間さん「どしたの?」
いぬ先生「今のSQLなんだけどちょっとパフォーマンスが良くないかも」
人間さん「どういうところ?」
いぬ先生「これだとSELECT文が2回ある分、テーブルスキャンを2回行っていることになる」
いぬ先生「なのでパフォーマンスは良くないかな」
いぬ先生「他に良い方法があるよ」
人間さん「でも別に良くない?」
人間さん「結果は同じなんでしょ?」
いぬ先生「まぁそうね」
いぬ先生「ただ、今回はデータも少ないからいいかもだけど」
いぬ先生「今後大量のデータを扱うときには速さが違ってくるから」
いぬ先生「良い機会だしCASE式を使ってみよう」
人間さん「頼もしい」
いぬ先生「さっきのからWHEREのconditionはCASEにかえて…」
いぬ先生「SELECTとUNIONを削って…」
いぬ先生「これでよしっと」
SELECT
id,
name,
condition,
price AS '元価格',
CASE WHEN condition = '良' THEN 300
WHEN condition = '悪' THEN 100
ELSE 200
END AS '新価格'
FROM
products
WHERE
name = 'りんご';
いぬ先生「これで結果は人間さんのと同じになる」
| id | name | condition | 元価格 | 新価格 |
|---|---|---|---|---|
| 1 | りんご | 良 | 20 | 300 |
| 3 | りんご | 悪 | 2000 | 100 |
人間さん「お~なんだかスッキリしたね」
いぬ先生「だけど、これだとテーブルスキャンが1回になるから」
いぬ先生「パフォーマンスも良くなって速度も上がるよ」
人間さん「ありがとう~」
人間さん「ん、ここの200ってなに?」
CASE WHEN condition = '良' THEN 300
WHEN condition = '悪' THEN 100
ELSE 200 -- この行のところ
END AS '新価格'
いぬ先生「これはデフォルト値で」
いぬ先生「いずれの条件にも一致しない場合は200円設定になるよってこと」
いぬ先生「今回のケースだとその対象がないから意味はなさないけど」
いぬ先生「ELSE句は書くように意識しよう」
人間さん「なんで?」
いぬ先生「これがないと各条件に漏れてしまった商品の金額がNULLになってしまう」
いぬ先生「CASE式の仕様によるものなんだ」
いぬ先生「なので、CASE式を使うときは、常に明示的にELSE句を書くようにしよう!」
人間さん「わかりました!」
UPDATEで使ってみる
人間さん「さて金額を修正するかな」
人間さん「良いりんごは300円」
人間さん「悪いりんごは100円っと」
UPDATE
products
SET
price = 300
WHERE
name = 'りんご'
condition = '良';
UPDATE
products
SET
price = 100
WHERE
name = 'りんご'
condition = '悪';
いぬ先生「度々失礼!」
いぬ先生「これもテーブルスキャンが2回行われてしまうから」
いぬ先生「CASE式を使ってパフォーマンス良くしようか」
人間さん「え、UPDATEでも使えるの!?」
いぬ先生「そう、SELECTと同じように使えるんだよ」
いぬ先生「UPDATEだとさっきの人間さんのSQLがこうなる」
UPDATE
products
SET
price = CASE WHEN condition = '良' THEN 300
WHEN condition = '悪' THEN 100
ELSE 200
END
WHERE
name = 'りんご';
いぬ先生「SET句のカラム名(price)は忘れずにね」
人間さん「(いつも忘れそうになる…)」
いぬ先生「実行!」
| id | name | condition | price |
|---|---|---|---|
| 1 | りんご | 良 | 300 |
| 2 | オレンジ | 悪 | 200 |
| 3 | りんご | 悪 | 100 |
| 4 | もも | 良 | 100 |
| 5 | オレンジ | 良 | 500 |
いぬ先生「更新うまくいったね!」
人間さん「助かりました~」