SELECT / WHERE / ORDER BY で結果を絞る
Docker の PostgreSQL_setup で practice_db に入れる前提です(docker compose up -d 済みならそのまま)。ここでは PostgreSQL を主に使い、練習用の products(6 行)を作りながら、SELECT で「全部取る」から「条件・並び・件数」までを手を動かして確認します。所要は 20〜30 分。
MySQL でも同じ流れで試せます。型やクライアントの差は MySQL で試す場合 にまとめています。
原本の環境: PostgreSQL_setup · MySQL_setup
目次
準備
cd $DB_SQL/PostgreSQL_setupdocker compose up -ddocker compose ps # Up (healthy) を確認docker compose exec db psql -U practice -d practice_dbプロンプトが practice_db=# になれば OK です。
サンプル表を作る
既存の表はそのまま残して構いません。練習用に別テーブルを足します。
CREATE TABLE IF NOT EXISTS products ( id SERIAL PRIMARY KEY, name TEXT NOT NULL, category TEXT NOT NULL, price INT NOT NULL, in_stock BOOLEAN NOT NULL DEFAULT TRUE);TRUNCATE products RESTART IDENTITY;INSERT INTO products (name, category, price, in_stock) VALUES ('ノート A5', 'stationery', 300, TRUE), ('ボールペン', 'stationery', 120, TRUE), ('USB-C ケーブル', 'gadget', 980, FALSE), ('ワイヤレスマウス', 'gadget', 2500, TRUE), ('付箋', 'stationery', 150, TRUE), ('HDMI 変換', 'gadget', 1800, TRUE);確認:
SELECT * FROM products;6 行出てくれば先に進みます。
SELECT の基本
全部の列:
SELECT * FROM products;列を指定:
SELECT name, price FROM products;式や別名:
SELECT name, price, price * 1.1 AS price_with_taxFROM products;AS は省略できますが、読み手のためにつけておくと後で楽です。
WHERE で絞る
等しい:
SELECT name, price FROM products WHERE category = 'gadget';比較:
SELECT name, price FROM products WHERE price >= 1000;論理:
SELECT name, price FROM productsWHERE category = 'stationery' AND price < 200;SELECT name, category FROM productsWHERE category = 'gadget' OR price < 200;NULL ではないかの確認(いまの表には NULL は無いが、書き方だけ):
SELECT * FROM products WHERE name IS NOT NULL;文字列の部分一致(PostgreSQL):
SELECT name FROM products WHERE name LIKE '%ケーブル%';真偽:
SELECT name FROM products WHERE in_stock = FALSE;ORDER BY と LIMIT
安い順:
SELECT name, price FROM products ORDER BY price ASC;高い順(DESC):
SELECT name, price FROM products ORDER BY price DESC;複数キー(カテゴリ、その中で価格):
SELECT category, name, priceFROM productsORDER BY category, price;先頭だけ:
SELECT name, price FROM productsORDER BY price DESCLIMIT 3;「高いものから 3 つ」が取れれば、並びと件数の組み合わせは押さえたことになります。
期待する結果の例(ORDER BY price DESC LIMIT 3):
| name | price |
|---|---|
| ワイヤレスマウス | 2500 |
| HDMI 変換 | 1800 |
| USB-C ケーブル | 980 |
ワンライナー例:
docker compose exec db psql -U practice -d practice_db -c \ "SELECT name, price FROM products WHERE category = 'gadget' ORDER BY price;"MySQL で試す場合
MySQL_setup に入り、healthy を確認してから:
cd $DB_SQL/MySQL_setupdocker compose up -ddocker compose exec db mysql -u practice -ppractice practice_db表定義だけ PostgreSQL と差が出ます(SERIAL → AUTO_INCREMENT、BOOLEAN → TINYINT(1) など)。
CREATE TABLE IF NOT EXISTS products ( id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(255) NOT NULL, category VARCHAR(64) NOT NULL, price INT NOT NULL, in_stock TINYINT(1) NOT NULL DEFAULT 1);TRUNCATE products;INSERT INTO products (name, category, price, in_stock) VALUES ('ノート A5', 'stationery', 300, 1), ('ボールペン', 'stationery', 120, 1), ('USB-C ケーブル', 'gadget', 980, 0), ('ワイヤレスマウス', 'gadget', 2500, 1), ('付箋', 'stationery', 150, 1), ('HDMI 変換', 'gadget', 1800, 1);SELECT name, price FROM productsWHERE category = 'gadget'ORDER BY price DESCLIMIT 3;SELECT / WHERE / ORDER BY / LIMIT の書き方自体は同じです。真偽は 0 / 1 で扱うのが無難です。
よくあるつまずき
| 症状 | 対処 |
|---|---|
relation "products" does not exist |
上の CREATE TABLE を実行した DB / ユーザーか確認 |
syntax error 付近に日本語 |
文字列はシングルクォート '...'(ダブルは識別子) |
MySQL で BOOLEAN が気になる |
MySQL では TINYINT(1) 相当。同じ INSERT でも動くことが多い |
| 結果が空 | WHERE が厳しすぎないか、先に SELECT * で件数確認 |
結果が空のとき、まず SELECT * に戻す癖は一度つくと楽です。
練習を消すとき:
DROP TABLE IF EXISTS products;環境ごと初期化するなら、セットアップフォルダで docker compose down -v です。
WHERE と ORDER BY / LIMIT が動けば、SELECT で結果を絞る基本は押さえられています。