SELECT・WHERE句で人を探す演習
概要
- 日程: Day 1 / セッション 7
- 時間: 13:30-14:15
- 形式: 実習
- ゴール: employees / products テーブルに対して、列指定・等価条件・大小比較を組み合わせたSELECT文を5本書ける
- 学習形式: ハンズオン実習(AIペアプログラミング)
導入(5分)
前のセッション6で、SELECT文の役割(射影=列を選ぶ、選択=行を選ぶ)と、WHERE句で行を絞り込む基本構文を学びました。理屈が分かったところで、ここからは実際に手を動かしてもらいます。
研修期間中、皆さんは何度も「sandboxにつないで psql を開く」ことになります。まずは psql のプロンプト sandbox=# が表示されている状態を確認してください。表示されていなければ、docker exec -it postgres-sandbox psql -U postgres -d sandbox で接続し直しましょう。
今日のテーマは「人を探す」「モノを探す」です。employees テーブルから人を、products テーブルからモノを、条件を変えて何度も探してみます。条件の書き方が変わると、結果がどう変わるか——その違いに注目してください。
本編(10分)
1. クエリは「読みやすく分けて書く」のがコツ
SQL は1行で書いてもエラーにはなりません。が、人間には読みづらく、デバッグ時に泣くことになります。本研修では、最初から以下のように改行して書く癖をつけましょう。
SELECT first_name, last_name, salary
FROM employees
WHERE salary >= 500000;
たとえると、料理のレシピを「材料・手順・仕上げ」と段落分けして書くのと同じです。後で「どこを変えたか」がすぐ分かります。
ここがポイント
SELECTの後に必要な列を,で並べる(全列なら*)FROMでテーブル名を指定WHEREで行の条件を書く- 文の終わりに
;(セミコロン)を忘れない
2. 文字列はシングルクォート、数値はそのまま
WHERE 句で条件を書くとき、文字列リテラルは必ず '(シングルクォート)で囲みます。数値はクォートなしで書きます。
-- OK:文字列は ' で囲む
SELECT * FROM employees WHERE last_name = '山田';
-- OK:数値はクォートなし
SELECT * FROM employees WHERE salary = 450000;
-- NG:文字列をダブルクォートで囲むと「列名」と解釈されてエラー
SELECT * FROM employees WHERE last_name = "山田";
PostgreSQL ではダブルクォート " は「列やテーブルの名前を強調する」記号です。文字列を囲むつもりで使うと「そんな列名はない」と怒られます。
ここがポイント
- 文字列:
'山田''gmail.com' - 数値:
4500003.14 - 日付:
'2020-04-01'(文字列扱いで書ける)
コラム
「シングルクォート問題」はSQLにおける永遠のネタです。1970年代のSQL設計者たちが「文字列は '、識別子は "」と決めた当時はシンプルでしたが、現代の多くのプログラミング言語では逆に ' と " を同義で使えるため、初心者は必ず1度はここで足元をすくわれます。世界中の入門者が同じ場所で転んでいると思うと、ちょっと気が楽になりませんか。
3. 比較演算子のラインナップ
WHERE 句で使える基本の演算子は次のとおりです。
| 演算子 | 意味 | 例 |
|---|---|---|
= |
等しい | salary = 450000 |
<> または != |
等しくない | department_id <> 1 |
> >= |
より大きい / 以上 | salary >= 500000 |
< <= |
より小さい / 以下 | price < 3000 |
ここで少し考えてみてください。「salary = 500000 の社員」と「salary >= 500000 の社員」、結果はどう違うでしょうか?前者は「ピッタリ50万円」のみ、後者は「50万円ちょうども含めて、それ以上の人全員」です。= と >= の1文字差が結果集合を大きく変える、というのが SQL の感覚です。
💬 AIに聞いてみよう
- 「
SELECT *と列を明示するの、実務ではどちらが推奨ですか?理由も知りたいです」 - 「
<>と!=の違いを教えてください。どちらを使うべき?」 - 「結果が0件のとき、SQLが間違っているのか、本当にデータがないのか、どう見分ければいい?」
実習・演習(25分)
課題
psql に接続した状態で、以下の5本のクエリを順に書いて実行してください。書いたSQLと、得られた結果(件数だけでもOK)をメモに残しましょう。
Q1. 営業部(department_id = 1)に所属する社員の、姓・名・給与だけを取得する
ヒント:列指定 + WHERE department_id = 1
Q2. 給与が50万円以上の社員の全列を取得する
ヒント:SELECT * + WHERE salary >= 500000
Q3. 給与が40万円未満の社員の姓・名・入社日・給与を、入社日が分かる形で取得する
ヒント:hire_date も列に含める
Q4. products テーブルから、価格が1万円以上の商品の名前と価格を取得する
ヒント:product_name, price + WHERE price >= 10000
Q5. products テーブルから、在庫が100個未満の商品の名前・カテゴリID・在庫数を取得する
ヒント:stock_quantity < 100
成果物
- 5本のSQLクエリ(
.sqlファイルにまとめて保存しておくと、後で見返せます) - 各クエリの結果件数のメモ
- 詰まったときにAIに送った質問・受け取った回答の記録(1〜2件で十分)
ヒント
- 結果が空(0行)でも、エラーが出ていなければ文法は合っています。「該当データがない」だけです。
SELECT COUNT(*) FROM employees;で全件数を確認してから条件を緩めてみましょう \xを psql で叩くと、結果が縦表示(拡張表示)になります。列が多くて折り返してしまうときに便利です- AI に頼むときは、「このSQLを書いて」ではなく「このSQLを書いてみたが結果が0件になる。なぜか考えるヒントをください」のように、自分の仮説を添えると学びが大きくなります
まとめ(5分)
一言でまとめると「SELECTは列を選ぶ、WHEREは行を選ぶ、' は文字列、クォートなしは数値」。この4つを身体に染み込ませることが、今日の前半のゴールでした。
次のセッションでは、ORDER BY による並び替えと、LIKE / IN / BETWEEN といったパターン検索の道具を学びます。「該当する人/モノを抽出する」から、「並べて見る」「もっと柔軟に絞り込む」へ進みます。
🔄 振り返りチェック
- 文字列条件で
=を使うとき、リテラルをどの記号で囲みますか? - 結果が0件のとき、まず最初に確認するのはどんなSQLですか?
SELECT *と列名を明示する書き方、それぞれのメリットはなんでしょうか?
補足資料
- 参考リンク: PostgreSQL: SELECT 構文
- 発展課題: employees から「メールアドレスが
@example.comで終わる社員」を抽出するSQLを、次セッションで習う前に予想で書いてみる(LIKEを使うことになるはず、と気づければ十分)
学習ガイド
想定される質問と回答例
| 質問 | ヒント |
|---|---|
| ダブルクォートとシングルクォートを間違えるとどんなエラーが出る? | column "山田" does not exist のようなメッセージ。「列名扱いされた」と読めれば原因が分かる |
WHERE first_name = '太郎' で結果が0件だが、データはあるはず |
全角・半角や前後の空白、漢字の異体字の可能性。SELECT DISTINCT first_name FROM employees; で実データを見る |
| セミコロンを忘れたらどうなる? | psqlのプロンプトが sandbox=# から sandbox-# に変わって入力待ちのままになる。; を打てば実行される |
| 列名を間違えるとどうなる? | column "xxx" does not exist エラー。\d employees で正しい列名を確認 |
つまずきやすいポイント
| つまずきポイント | ヒント |
|---|---|
' のつもりが ’(全角)になっている |
エディタの設定を見直す。psql に直接打つほうが安全 |
| 大文字小文字を気にしすぎる | SQLキーワード(SELECT/WHERE)も列名も基本は大小区別なし。文字列リテラルの中身は区別あり |
WHERE の条件をカンマで区切ってしまう |
カンマは SELECT の列区切りだけ。WHERE 内の複数条件は AND OR でつなぐ(次セッションで詳説) |
| 結果が想定と違うときAIに丸投げ | 「自分はこう予想したのに、こう出た」と仮説を添えて聞くと、AIの説明も的確になる |