Myポケモンずかんを作ってSQL文での四大命令文とNULLについて整理してみた
プログラミング学習のアウトプットとして記事にまとめました🐣
学習最中のエンジニア志願者の理解整理に役立てれば幸いです✨
4つの基本的な命令(四大命令文)
テーブルに登録されてあるデータを操作するSQL文は以下の四大命令文を使用します。
- SELECT(選択) :データを取得
- INSERT(挿入) :データを追加
- UPDATE(更新) :データを更新
- DELETE(削除) :データを削除
このまま使用してしまうと全てのデータが対象になってしまうので
ある条件で絞り込みたい…
そんなときには、WHERE句を使用します。
WHERE句の特徴
- 該当する条件がある行をだけを絞り込んで選択できる(デフォは全て対象)
- SELECT文、UPDATE文、DELETE文には使用できる(INSERT文は使えない)
- WHEREのあとには条件式
条件式が複数になった場合
条件式を複数にしたい場合は、論理演算子'NOT'や'AND'、'OR'で繋げることができます。
ポケモン様のお力をお借りします🙇🏻♀️
(例)オリジナルポケモンずかんっぽいもの
データベース 「db_Pokemon」
テーブル 「profile」
+----+-----------------+-----------+
| id | name | type |
+----+-----------------+-----------+
| 1 | ピカチュウ | でんき |
| 2 | カイリュー | ひこう |
| 3 | ヤドラン | みず |
| 4 | ピジョン | ひこう |
| 5 | コダック | みず |
+----+-----------------+-----------+
ここからちょっといたずらをします。
ピカチュウのときと、みずタイプのとき
かわいいタイプに変えちゃいましょう。((ぇ
UPDATE profile
SET type = 'かわいい'
WHERE name = 'ピカチュウ' OR type = 'みず';
+----+-----------------+--------------+
| id | name | type |
+----+-----------------+--------------+
| 1 | ピカチュウ | かわいい |
| 2 | カイリュー | ひこう |
| 3 | ヤドラン | かわいい |
| 4 | ピジョン | ひこう |
| 5 | コダック | かわいい |
+----+-----------------+--------------+
ANDとORを同時に使うとき
はい、最初の状態に戻しまして、ANDとORを同時に使いたい場合を考えます。
ここにteamフィールドを追加します。
+----+-----------------+-----------+-------+
| id | name | type | team |
+----+-----------------+-----------+-------+
| 1 | ピカチュウ | でんき | A |
| 2 | カイリュー | ひこう | A |
| 3 | ヤドラン | みず | A |
| 4 | ピジョン | ひこう | B |
| 5 | コダック | みず | B |
+----+-----------------+------------+-------+
①ひこうタイプのときか、みずタイプのとき
かつ
②チームA
なら小悪魔タイプに更新します😈
①と②両方の条件を満たすのはカイリュー、ヤドランだけです。
では当てはめてみましょう。
UPDATE profile
SET type = '小悪魔'
WHERE type = 'ひこう' OR type = 'みず' AND team = 'A';
+----+-----------------+-----------+-------+
| id | name | type | team |
+----+-----------------+-----------+-------+
| 1 | ピカチュウ | でんき | A |
| 2 | カイリュー | 小悪魔 | A |
| 3 | ヤドラン | 小悪魔 | A |
| 4 | ピジョン | 小悪魔 | B |
| 5 | コダック | みず | B |
+----+-----------------+------------+-------+
…ピジョンまで小悪魔に!
これではちょっと期待していた結果とは異なってしまいます。
なぜかというと、
演算子には優先順位があり、
ANDとORでは
ANDが優先されてしまうので
結果が変わってきてしまうのです!
こちら参考です。
ORの優先度高くしたいときには、
①の式を()で囲うと
()内が優先されて、解決します!
算数の四則演算のときに使う()みたいですねー!
UPDATE profile
SET type = '小悪魔'
WHERE (type = 'ひこう' OR type = 'みず') AND team = 'A';
結果は、
+----+-----------------+-----------+-------+
| id | name | type | team |
+----+-----------------+-----------+-------+
| 1 | ピカチュウ | でんき | A |
| 2 | カイリュー | 小悪魔 | A |
| 3 | ヤドラン | 小悪魔 | A |
| 4 | ピジョン | ひこう | B |
| 5 | コダック | みず | B |
+----+-----------------+------------+-------+
意図した通りの結果になってくれました🎉
NULLについて
さらにポケモンずかんらしくゲットした日時を入れるフィールドを追加してみます。
-- ゲットした日時のフィールドを追加
ALTER TABLE profile
ADD COLUMN catch_date DATETIME;
-- 既にゲットしたポケモンに日時を設定
UPDATE profile
SET catch_date = '2024-08-01 10:00:00'
WHERE name = 'ピカチュウ';
-- まだゲットしていないポケモンにNULLを設定
-- (デフォはNULLなので必要ないですが後の説明で使うので記載しました)
UPDATE profile
SET catch_date = NULL
WHERE name IN ('カイリュー', 'ヤドラン', 'ピジョン', 'コダック');
+----+-----------------+-----------+---------------------+
| id | name | type | catch_date |
+----+-----------------+-----------+---------------------+
| 1 | ピカチュウ | でんき | 2024-08-01 10:00:00 |
| 2 | カイリュー | ひこう | NULL |
| 3 | ヤドラン | みず | NULL |
| 4 | ピジョン | ひこう | NULL |
| 5 | コダック | みず | NULL |
+----+-----------------+-----------+---------------------+
最初はピカチュウだけで他はまだゲットしていないので空欄のNULLになります。
さてさて、物語を進めていくと…
あっ!
野生のピジョンがとびだしてきた!
いけっ!モンスターボール!
…
…
…
やったー!ピジョンをゲットした!
名前はピジョンで、まだゲットしていなければ、ゲットした時点の日時を更新します。
UPDATE profile
SET catch_date = NOW()
WHERE name = 'ピジョン' AND catch_date = NULL;
+----+-----------------+-----------+---------------------+
| id | name | type | catch_date |
+----+-----------------+-----------+---------------------+
| 1 | ピカチュウ | でんき | 2024-08-01 10:00:00 |
| 2 | カイリュー | ひこう | NULL |
| 3 | ヤドラン | みず | NULL |
| 4 | ピジョン | ひこう | NULL |
| 5 | コダック | みず | NULL |
+----+-----------------+-----------+---------------------+
あれ、更新されませんねー🫠
ここでポイントになるのが、
先ほどの-- まだゲットしていないポケモンにNULLを設定
では= NULL
が使えましたが、
WHERE句の中ではIS NULL
を使うルールになっています。
UPDATE profile
SET catch_date = NOW()
WHERE name = 'ピジョン' AND catch_date IS NULL;
+----+-----------------+-----------+---------------------+
| id | name | type | catch_date |
+----+-----------------+-----------+---------------------+
| 1 | ピカチュウ | でんき | 2024-08-01 10:00:00 |
| 2 | カイリュー | ひこう | NULL |
| 3 | ヤドラン | みず | NULL |
| 4 | ピジョン | ひこう | 2024-08-17 18:37:40 |
| 5 | コダック | みず | NULL |
+----+-----------------+-----------+---------------------+
無事更新されました🦅
MyポケモンずかんでDBを作成してみました。
1つのカラムには1つのデータを格納するのが基本だそうです。
カイリューのようにひこうタイプとドラゴンタイプで2つ属性タイプを持つポケモンもいましたがとりあえず今回は1つだけにしました。
複数の属性タイプを格納したい場合は
- profileテーブルに基本情報
- typesテーブルに属性タイプ
というように、テーブルを分けて管理するようです。
(,)で区切って2つ以上格納しようと思えばできるけど、
データの検索や更新が難しくなるため、あまり推奨されないとのことです。
簡単なポケモンずかんのDBひとつ作るのにも奥が深い…👾笑
ここまでお読みいただきありがとうございました!
間違い等ございましたらご指摘よろしくお願いします🙇🏻♀️
Discussion