DB/SQL

SELECT / WHERE / ORDER BY で結果を絞る

3

SELECT / WHERE / ORDER BY で結果を絞る

Docker の PostgreSQL_setuppractice_db に入れる前提です(docker compose up -d 済みならそのまま)。ここでは PostgreSQL を主に使い、練習用の products(6 行)を作りながら、SELECT で「全部取る」から「条件・並び・件数」までを手を動かして確認します。所要は 20〜30 分。

MySQL でも同じ流れで試せます。型やクライアントの差は MySQL で試す場合 にまとめています。

原本の環境: PostgreSQL_setup · MySQL_setup


目次

  1. 準備
  2. サンプル表を作る
  3. SELECT の基本
  4. WHERE で絞る
  5. ORDER BY と LIMIT
  6. MySQL で試す場合
  7. よくあるつまずき

準備

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 と差が出ます(SERIALAUTO_INCREMENTBOOLEANTINYINT(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 です。

WHEREORDER BY / LIMIT が動けば、SELECT で結果を絞る基本は押さえられています。

シェア