ここでは、初心者から実践的に学べるプログラミングスクール「ウェブカツ!!」のPHP・MySQL部入門またはWEBサービス部を受講している生徒の方向けに、さらに「SQL」についての理解度を上げるため特訓をしていきます。
ここからは、WEBサービス部で初めて出てくる内容を元に特訓をするので、まだWEBサービス部を1周見ていない人は見てからにしてください。
出題の回答は全て「SQL言語」を使って答えてください。
DBソフトの種類によってSQL言語は微妙に違いますが(と言っても基本の書き方はどれも同じなのでどのDBでも使える知識です)、ここでは「MySQL」を元にしたSQLの書き方を特訓していきます。
必ず実際にMySQLを動かしてphpMyAdminから問題のテーブルを作成してSQLを実行(「SQL」というタブから行えます)しましょう。(じゃないと練習にならないので)
鬼練15:君と結合したいんだ!
いや、いやらしい意味じゃないんですホント。
仕様書
下記要件に従ってSQLを記述してください。
下記の構造のテーブル「users」「products」をphpMyAdminから作成し、そのテーブルにレコードを入れてください
挿入するデータは下記の5つです。
○users1つ目のデータ
id:連番(1)
name:ウェブカツおじさん
email:test@test.com
gender:1
○users2つ目のデータ
id:連番(2)
name:筋トレおじさん
email:test@test.com
gender:1
○products1つ目のデータ
id:連番(1)
user_id:2
name:プロテイン
detail:ホエイプロテインです。筋肉の生成に必要なものです。
○products2つ目のデータ
id:連番(2)
user_id:2
name:HMB
detail:HMBは筋肉の生成を促進します。プロテインと併用すると効果的です。プロテインを摂取せずにHMBを摂るだけでも筋肉はついていきます。
○products3つ目のデータ
id:連番(3)
user_id:3
name:ダンベル
detail:ダンベルはトレイニーには必須の器具です。挙げてもよし。振ってもよし。
としてください。
上記データから
ユーザーIDが1と2のユーザーのユーザー情報と商品テーブルのレコードとカラムを「全て」
取得してください。
また、
商品情報がない場合でもユーザー情報を取得してください。
ヒント
実は、これ出来ません。
商品テーブルの「外部キー制約」を外さないとそもそも「存在しないユーザー」の商品情報なんて登録出来ないからです。
試しにINSERT文で入れてみてください。エラーになるので。(ちなみに「挿入」タブからやろうとするとuser_idカラムには、そもそも存在するユーザーしか選択できなくなってます)
なので、外部キー制約は外して試してみましょう。
答え
では、SQL文の答えです。
1 |
SELECT * FROM users AS u LEFT JOIN products AS p ON u.id = p.user_id WHERE u.id = 1 OR u.id = 2 |
または
1 |
SELECT * FROM products AS p RIGHT JOIN users AS u ON u.id = p.user_id WHERE u.id = 1 OR u.id = 2 |
こうですね。
商品情報がなかったとしても、対象のユーザーテーブルの情報は取得したい。
わけなので、さっきと逆バージョンです。
取得するカラムの指定は前回やったようによしなに(適当に)つけてくださいね。今回は簡単に「*」つかってますが。
1 |
WHERE p.user_id = 1 OR p.user_id = 2 |
1 |
WHERE u.id = 1 OR u.id = 2 |
でもいいはずですね。(ON句でお互いのカラムが紐づいているので)
やってみて。
他にもSQLは書き方によってパフォーマンスが違ってくるので、現場1年目では気にする必要ありませんが、下記のサイトのように更に深いところまで勉強したい人はどうぞ。
ただ、こういう部分の勉強は優先順位としては低いです。(そもそもフリーランスで年1千万だったら、こういう知識なくても十分稼げるので)
なぜ、SQLは重たくなるのか?──『SQLパフォーマンス詳解』の翻訳者が教える原因と対策
ここまでが、DBでのCRUD処理(Create、Read、Update、Deleteの頭文字を取って「クラッド」)です。(あと「サブクエリ」なんてものもあるので自分でググってみてください)
やってきて分かったかと思いますが、ほぼ
SELECT文どう書くか
が圧倒的に内容が濃いわけです。
単にデータを入れたり、更新したり、削除したりするのはなんて事ないわけです。
「保存されたデータをどう取ってくるか?」
がどんなサービスであろうと「肝」なわけですね。
もっと言えば、そもそも
テーブルどう作るか?
という「テーブル設計」が一番の肝です。
ここで失敗するとデータの更新が大変になったり(データの整合性保つのが大変)、無駄が多くなり、
データが増えていくほどにデータを取得したり更新する時にパフォーマンスが落ちる
ということになっていきます。