PostgreSQL入門#2: SELECT文の基本

SELECT文の基本

SQLでデータを取り出すときに使うのが SELECT文 です。基本的な書き方から、よく使うオプションまで整理します。

基本構文

SELECT カラム名1, カラム名2, ...
FROM テーブル名;

例: users テーブルから名前とメールを取得

SELECT name, email
FROM users;

すべてのカラムを取得

SELECT * 
FROM users;

* は「全カラム」を意味します。

条件を指定(WHERE句)

SELECT name, age
FROM users
WHERE age >= 30;

age が30以上のユーザーだけ取得。

並び替え(ORDER BY句)

SELECT name, age
FROM users
ORDER BY age DESC;

年齢を降順(大きい順)で並べる。
ASC(昇順)がデフォルト。

取得件数を制限(LIMIT句)

SELECT name, email
FROM users
LIMIT 5;

先頭5件だけ取得。

オフセット(スキップ)と組み合わせも可能:

SELECT name, email
FROM users
LIMIT 5 OFFSET 10;

10件スキップして11件目から5件取得。

重複をなくす(DISTINCT)

SELECT DISTINCT category
FROM products;

重複を取り除いたカテゴリー一覧を取得。

集計(GROUP BY & 集約関数)

SELECT category, COUNT(*) AS total
FROM products
GROUP BY category;

カテゴリーごとに商品数を数える。
よく使う集約関数には COUNT, SUM, AVG, MAX, MIN があります。

条件付き集計(HAVING句)

SELECT category, COUNT(*) AS total
FROM products
GROUP BY category
HAVING COUNT(*) >= 10;

商品数が10以上のカテゴリーだけ取得。

まとめ

  • SELECT ... FROM ... が基本
  • WHERE で条件
  • ORDER BY で並び替え
  • LIMIT で件数制限
  • DISTINCT で重複除去
  • GROUP BY / HAVING で集計

これらを組み合わせることで、柔軟にデータを取り出せます。

列に別名をつける方法

PostgreSQLで列(カラム)に別名を付けるには AS句 を使います。これを「エイリアス」と呼びます。見やすい名前にしたり、計算列にラベルを付けるときに便利です。

基本構文

SELECT カラム名 AS 別名
FROM テーブル名;

例: users テーブルで name 列を「username」として表示

SELECT name AS username
FROM users;

AS は省略も可能です。

SELECT name username
FROM users;

計算結果に別名を付ける

SELECT price * quantity AS total_price
FROM orders;

計算式にわかりやすい名前を付けられます。

集約関数に別名を付ける

SELECT COUNT(*) AS user_count
FROM users;

別名にスペースや大文字を含めたい場合

ダブルクォートで囲みます。

SELECT name AS "User Name"
FROM users;

この場合は結果を参照する際にも "User Name" とクォートが必要です。

まとめ

  • AS で列に別名を付けられる(省略可)
  • 計算列や集約関数の結果に名前を付けると見やすい
  • スペースや大文字を維持したいときはダブルクォートで囲む

これを使うとクエリ結果の可読性がぐっと上がります。

WHERE句の具体的な使い方やテクニック

WHERE 句は、SQLで 条件を絞り込むための句 です。PostgreSQLでは柔軟な条件指定が可能で、さまざまなテクニックがあります。

基本構文

SELECT カラム名
FROM テーブル名
WHERE 条件;

例: 年齢が30以上のユーザーを取得

SELECT name, age
FROM users
WHERE age >= 30;

複数条件の組み合わせ

  • AND: 両方の条件を満たす
  • OR: どちらかの条件を満たす
  • NOT: 否定
SELECT name
FROM users
WHERE age >= 20 AND age < 30;

SELECT name
FROM users
WHERE city = 'Tokyo' OR city = 'Osaka';

SELECT name
FROM users
WHERE NOT (age < 18);

比較演算子

  • =(等しい)
  • <> または !=(等しくない)
  • <, >, <=, >=
SELECT *
FROM products
WHERE price <> 1000;

部分一致・パターン検索

  • LIKE: ワイルドカード検索
    • % = 任意の長さの文字列
    • _ = 任意の1文字
  • ILIKE: 大文字小文字を区別しないLIKE
SELECT *
FROM users
WHERE name LIKE 'T%';     -- Tで始まる名前

範囲検索(BETWEEN)

SELECT *
FROM orders
WHERE order_date BETWEEN '2023-01-01' AND '2023-12-31';

値の集合に一致(IN)

SELECT *
FROM users
WHERE city IN ('Tokyo', 'Osaka', 'Nagoya');

NULLの判定

SELECT *
FROM users
WHERE phone IS NULL;

SELECT *
FROM users
WHERE phone IS NOT NULL;

複雑な条件式

カッコでグループ化することで優先順位を制御できます。

SELECT *
FROM users
WHERE (city = 'Tokyo' OR city = 'Osaka')
  AND age >= 20;

サブクエリを使った絞り込み

SELECT *
FROM users
WHERE id IN (SELECT user_id FROM orders WHERE total > 10000);

実用的なテクニック

  • EXISTS: サブクエリの存在チェック
SELECT *
FROM users u
WHERE EXISTS (SELECT 1 FROM orders o WHERE o.user_id = u.id);
  • 正規表現マッチ(PostgreSQL独自)
SELECT *
FROM users
WHERE email ~* '^[a-z0-9._%+-]+@example\.com$';

~ が正規表現一致、~* は大文字小文字を無視。

まとめ

  • 比較・論理演算子でシンプルな条件
  • LIKE, IN, BETWEEN で便利な検索
  • NULL, EXISTS, サブクエリで柔軟な絞り込み
  • PostgreSQL特有の 正規表現検索 も活用可能

これらを組み合わせれば、かなり高度な条件検索ができます。

SELECTでの算術演算子の使い方

PostgreSQLの SELECT 文では、数値型のカラムや定数に 算術演算子 を使うことで計算を行い、その結果を取得できます。よく使う算術演算子と具体例を整理します。

主な算術演算子

  • + 加算
  • - 減算
  • * 乗算
  • / 除算(整数同士でも小数を返す)
  • % 剰余(余り)

基本的な使い方

SELECT price, quantity, price * quantity AS total
FROM orders;

price × quantity を計算し、total という列名で出力。

定数との計算

SELECT name, salary, salary * 1.1 AS salary_with_bonus
FROM employees;

→ 給与に10%上乗せした値を計算。

複数演算の組み合わせ

演算子の優先順位は通常の数学と同じ(*/+- より先)。
必要なら括弧で明示します。

SELECT (price * quantity) - discount AS net_total
FROM orders;

剰余演算(%)

SELECT id, age, age % 2 AS is_even
FROM users;

age が偶数なら 0、奇数なら 1 を返す。

NULLを含む場合の注意

NULLを含む計算結果はNULLになります。
例:

SELECT price + discount FROM products;

discount がNULLなら結果もNULL。
NULLを回避するには COALESCE を利用:

SELECT price + COALESCE(discount, 0) FROM products;

まとめ

  • + - * / % が使える
  • 定数や複数カラムを組み合わせて計算可能
  • AS で別名を付けると結果が見やすい
  • NULLを考慮するなら COALESCE を活用

これを使えば、データ取得と同時に計算も行えるので、集計やレポートに便利です。

COALESCEとは?

COALESCE(コアレス)は、NULL値を扱うための関数です。指定した引数の中から最初に「NULLでない値」を返します。

基本構文

COALESCE(値1, 値2, 値3, ...)
  • 左から順に評価していき、最初にNULLでないものを返す
  • すべてNULLなら結果はNULL

使い方の例

NULLを0に置き換える

SELECT COALESCE(discount, 0) AS discount_value
FROM products;

discount がNULLなら 0 が返る

複数候補を用意する

SELECT COALESCE(phone, mobile, '未登録') AS contact
FROM users;

phone がNULLなら mobile を使い、それもNULLなら '未登録' を返す

計算式で利用

SELECT price + COALESCE(discount, 0) AS final_price
FROM products;

discount がNULLでも計算できる

使いどころ

  • データにNULLが含まれているときにデフォルト値を設定したい場合
  • NULLを含んだ計算を避けたい場合
  • 表示用に「未登録」や「不明」といった文字列を入れたい場合

まとめ

  • COALESCE は「最初にNULLでない値」を返す関数
  • NULLを安全に扱えるようになり、計算や表示がスムーズになる
  • デフォルト値代入やNULL回避の定番テクニックとしてよく使われる

SELECTで使える便利関数

文字列操作

CONCATまたは||:文字列を結合する

SELECT CONCAT(first_name, ' ', last_name) AS full_name FROM users;
SELECT first_name || ' ' || last_name AS full_name FROM users;

UPPER / LOWER:大文字・小文字に変換

SELECT UPPER(name), LOWER(name) FROM users;

LENGTH:文字数を返す

SELECT LENGTH(name) FROM users;

SUBSTRING:部分文字列を抽出

SELECT SUBSTRING(name FROM 1 FOR 3) FROM users;  -- 先頭3文字

日付・時刻

NOW:現在の日時を返す

SELECT NOW();

CURRENT_DATE / CURRENT_TIME:今日の日付や現在時刻を返す
AGE:2つの日付の差を年・月・日で返す

SELECT AGE(CURRENT_DATE, birth_date) FROM users;

DATE_TRUNC:日付を指定単位に丸める

SELECT DATE_TRUNC('month', order_date) AS month_start FROM orders;

数値の操作

ROUND:四捨五入

SELECT ROUND(price, 2) FROM products;  -- 小数点以下2桁に丸める

CEIL/FLOOR:切り上げ・切り捨て

SELECT CEIL(price), FLOOR(price) FROM products;

RANDOM():0以上1未満の乱数を返す

SELECT RANDOM();

集約関数とGROUP BYの使い方

集約関数GROUP BY はよく一緒に出てきますが、必ずしもセットで使う必要はありません。それぞれの役割を整理して説明します。

集約関数とは

テーブルの複数行をまとめて「1つの値」にする関数です。代表的なものは以下です。

  • COUNT() レコード数を数える
  • SUM() 合計
  • AVG() 平均
  • MAX() 最大値
  • MIN() 最小値

例: ユーザー数を数える

SELECT COUNT(*) FROM users;

GROUP BY は不要。テーブル全体に対して1つの結果を返します。

GROUP BYとは

データを「グループ単位」にまとめて、その単位ごとに集約関数を使えるようにする句です。

例: 都市ごとのユーザー数

SELECT city, COUNT(*) AS user_count
FROM users
GROUP BY city;

city ごとにグループ化して、その中で COUNT を計算。

集約関数とGROUP BYの関係

  • 集約関数だけ → テーブル全体に対する集計
  • GROUP BYあり → グループごとに集計

つまり、集約関数を使うときに 「列ごとにまとめたい」 なら GROUP BY が必要になります。

HAVINGとの組み合わせ

WHERE が「行」に対する条件なのに対し、HAVING は「グループ」に対する条件を絞るために使います。

例: ユーザー数が10人以上の都市だけ表示

SELECT city, COUNT(*) AS user_count
FROM users
GROUP BY city
HAVING COUNT(*) >= 10;

まとめ

  • 集約関数単体 → 全体の集計を出すとき(例: 全ユーザー数)
  • 集約関数 + GROUP BY → グループごとの集計を出すとき(例: 都市ごとのユーザー数)
  • HAVING → グループ化した結果に条件をかけたいとき

ORDER BYによる並び替えテクニック

ORDER BYSELECT文の結果を並び替える ための句です。基本的な使い方から便利なテクニックまでまとめます。

基本構文

SELECT カラム1, カラム2, ...
FROM テーブル名
ORDER BY 並び替え基準 [ASC|DESC];
  • ASC = 昇順(小さい→大きい)※デフォルト
  • DESC = 降順(大きい→小さい)

例: 年齢の昇順に並べる

SELECT name, age
FROM users
ORDER BY age ASC;

例: 年齢の降順に並べる

SELECT name, age
FROM users
ORDER BY age DESC;

複数カラムで並べ替え

複数条件を組み合わせて並び替えることも可能です。

SELECT name, city, age
FROM users
ORDER BY city ASC, age DESC;

→ まず city を昇順、その中で age を降順に並べる。

別名や計算式を使う

SELECT で付けた エイリアス や、計算結果を並び替えに利用できます。

SELECT name, price * quantity AS total
FROM orders
ORDER BY total DESC;

NULLの扱い

PostgreSQLでは NULLの並び順を指定 できます。

  • NULLS FIRST: NULLを先頭に
  • NULLS LAST: NULLを末尾に
SELECT name, age
FROM users
ORDER BY age ASC NULLS LAST;

ランダムな並び替え

SELECT *
FROM users
ORDER BY RANDOM();

→ データをランダムに取得(サンプリングに便利)。

LIMITとの組み合わせ

よく使うのは 並び替え + 件数制限 です。
例: 年齢が高い順に上位5人

SELECT name, age
FROM users
ORDER BY age DESC
LIMIT 5;

まとめ

  • ORDER BY カラム ASC|DESC で並び替え
  • 複数カラム指定で優先順位を付けられる
  • エイリアスや計算式も利用可能
  • NULLS FIRST / NULLS LAST でNULLの位置を制御
  • LIMIT と組み合わせてランキングやトップNを簡単に取得

これを使うと「ランキング」「最新データ取得」「ソート付き集計」などが自由にできます。

CASEを使う条件分岐

CASE 式は SQLで条件分岐を実現するための仕組み で、プログラミング言語の if 文のように使えます。SELECT文の中で使うと、値を条件に応じて切り替えられるのでとても便利です。

基本構文

単純CASE式(特定の値に応じて分岐)

CASE 式
  WHEN 値1 THEN 結果1
  WHEN 値2 THEN 結果2
  ...
  ELSE デフォルト結果
END

検索CASE式(条件式に応じて分岐)

CASE
  WHEN 条件1 THEN 結果1
  WHEN 条件2 THEN 結果2
  ...
  ELSE デフォルト結果
END

基本的な例

年齢を区分ごとに分類

SELECT name, age,
  CASE
    WHEN age < 20 THEN '未成年'
    WHEN age >= 20 AND age < 65 THEN '成人'
    ELSE 'シニア'
  END AS age_group
FROM users;

age_group 列に「未成年」「成人」「シニア」とラベルを付与。

単純CASEの例

SELECT product_name, category,
  CASE category
    WHEN 'A' THEN '食品'
    WHEN 'B' THEN '衣料'
    WHEN 'C' THEN '家電'
    ELSE 'その他'
  END AS category_name
FROM products;

category'A' なら「食品」、 'B' なら「衣料」などに変換。

集計で使う

CASEは集計関数と組み合わせると強力です。

条件付きカウント

SELECT
  COUNT(*) AS total_users,
  COUNT(CASE WHEN age < 20 THEN 1 END) AS minors,
  COUNT(CASE WHEN age >= 20 THEN 1 END) AS adults
FROM users;

→ 全体数・未成年数・成人数を一度に算出。

条件付き合計

SELECT
  SUM(CASE WHEN status = 'paid' THEN amount ELSE 0 END) AS paid_total,
  SUM(CASE WHEN status = 'unpaid' THEN amount ELSE 0 END) AS unpaid_total
FROM orders;

→ 支払い済みと未払いの金額を別々に集計。

ORDER BYで使う

並び替えの条件にCASEを組み込むことも可能です。

SELECT name, role
FROM users
ORDER BY
  CASE role
    WHEN 'admin' THEN 1
    WHEN 'staff' THEN 2
    ELSE 3
  END;

adminstaff → それ以外 の順に並べ替え。

注意点

  • CASE の評価は上から順に行われる(最初に一致したものが採用される)
  • ELSE を省略すると、条件に当てはまらない場合はNULLになる
  • 集計や並び替えに組み込むととても強力

まとめ

  • 単純CASE: 特定の値に応じて切り替える
  • 検索CASE: 条件式に応じて切り替える
  • 集計やORDER BY と組み合わせると分析・整形に役立つ

SQLだけで柔軟なデータ加工ができるので、実務でよく使われるテクニックです。

-PostgreSQL, SQL