はじめに
データベースを操作する上で最も基本的かつ頻繁に使用するのがSELECT文です。アプリケーション開発においてデータの取得は避けて通れない作業であり、SELECT文を適切に書けるかどうかが開発効率に直結します。
本記事では、PostgreSQLにおけるSELECT文の基本構文から、WHERE句による条件指定、ORDER BY/LIMIT/OFFSETによる並び替えとページング、集計関数(COUNT/SUM/AVG/MAX/MIN)とGROUP BY、DISTINCT、エイリアスの活用まで、実践的なサンプルコードとともに解説します。
この記事を読むことで、以下のことができるようになります。
- SELECT文の基本構文を理解し、テーブルからデータを取得できる
- WHERE句を使って必要なデータだけを抽出できる
- ORDER BY/LIMIT/OFFSETで結果の並び替えとページングを実装できる
- 集計関数とGROUP BYを使ってデータの集計・分析ができる
- DISTINCTとエイリアスを活用してクエリを効率的に記述できる
前提条件
- PostgreSQL 14以降がインストールされていること
- psqlまたはGUIツール(pgAdmin、DBeaver等)でデータベースに接続できること
- 基本的なデータベースの概念(テーブル、行、列)を理解していること
サンプルデータの準備
本記事で使用するサンプルテーブルとデータを準備します。以下のSQLを実行してください。
|
|
SELECT文の基本構文
全カラムを取得する
最もシンプルなSELECT文は、テーブルから全てのカラムを取得する形式です。アスタリスク(*)を使用することで、テーブル内の全カラムを一度に取得できます。
|
|
実行結果:
| product_id | name | category | price | stock | created_at |
|---|---|---|---|---|---|
| 1 | ノートPC | 電子機器 | 120000 | 25 | 2026-01-03 … |
| 2 | マウス | 電子機器 | 3500 | 150 | 2026-01-03 … |
| … | … | … | … | … | … |
ただし、本番環境ではSELECT *の使用は推奨されません。必要なカラムを明示的に指定することで、以下のメリットがあります。
- ネットワーク転送量の削減
- クエリの意図が明確になる
- テーブル構造の変更に対する耐性向上
特定のカラムを取得する
必要なカラムのみを取得する場合は、カラム名をカンマ区切りで列挙します。
|
|
実行結果:
| name | category | price |
|---|---|---|
| ノートPC | 電子機器 | 120000 |
| マウス | 電子機器 | 3500 |
| キーボード | 電子機器 | 8000 |
| … | … | … |
SELECT文の処理順序
SELECT文は記述順と実行順が異なります。理解しておくとクエリのデバッグに役立ちます。
flowchart TD
A["1. FROM句 - テーブルの特定"] --> B["2. WHERE句 - 行のフィルタリング"]
B --> C["3. GROUP BY句 - グループ化"]
C --> D["4. HAVING句 - グループのフィルタリング"]
D --> E["5. SELECT句 - カラムの選択・計算"]
E --> F["6. DISTINCT - 重複排除"]
F --> G["7. ORDER BY句 - 並び替え"]
G --> H["8. LIMIT/OFFSET - 結果の制限"]WHERE句による条件指定
基本的な比較演算子
WHERE句を使用して、条件に合致する行のみを取得できます。
| 演算子 | 説明 | 使用例 |
|---|---|---|
= |
等しい | price = 3500 |
<> または != |
等しくない | category <> '家具' |
< |
より小さい | price < 10000 |
> |
より大きい | stock > 50 |
<= |
以下 | price <= 50000 |
>= |
以上 | stock >= 20 |
|
|
実行結果:
| name | price |
|---|---|
| マウス | 3500 |
| キーボード | 8000 |
| デスクライト | 6500 |
| ペン(10本セット) | 500 |
論理演算子(AND, OR, NOT)
複数の条件を組み合わせる場合は論理演算子を使用します。
|
|
実行結果:
| name | category | price |
|---|---|---|
| ノートPC | 電子機器 | 120000 |
| モニター | 電子機器 | 55000 |
|
|
BETWEEN句
範囲を指定する場合はBETWEEN句が便利です。
|
|
実行結果:
| name | price |
|---|---|
| キーボード | 8000 |
| ヘッドセット | 12000 |
| 本棚 | 28000 |
| デスクライト | 6500 |
BETWEENは境界値を含む(両端を含む)ことに注意してください。
IN句
複数の値のいずれかに一致するかを判定する場合はIN句を使用します。
|
|
LIKE句によるパターンマッチング
文字列の部分一致検索にはLIKE句を使用します。
| パターン | 説明 |
|---|---|
% |
0文字以上の任意の文字列 |
_ |
任意の1文字 |
|
|
実行結果(1つ目のクエリ):
| name | price |
|---|---|
| ノートPC | 120000 |
NULL値の判定
NULL値の判定にはIS NULLまたはIS NOT NULLを使用します。= NULLでは正しく判定できません。
|
|
ORDER BYによる並び替え
昇順と降順
ORDER BY句を使用して結果を並び替えられます。
|
|
ASCは省略可能で、デフォルトは昇順です。
実行結果(降順):
| name | price |
|---|---|
| ノートPC | 120000 |
| モニター | 55000 |
| デスク | 45000 |
| オフィスチェア | 35000 |
| … | … |
複数カラムでの並び替え
複数のカラムで並び替える場合は、カンマ区切りで指定します。最初のカラムで同じ値の場合、次のカラムで並び替えられます。
|
|
実行結果:
| name | category | price |
|---|---|---|
| オフィスチェア | 家具 | 35000 |
| デスク | 家具 | 45000 |
| … | … | … |
| ノートPC | 電子機器 | 120000 |
| モニター | 電子機器 | 55000 |
| … | … | … |
NULLの扱い
ORDER BYでのNULL値の扱いは、NULLS FIRSTまたはNULLS LASTで制御できます。
|
|
LIMITとOFFSETによるページング
取得件数を制限する
LIMIT句で取得する行数を制限できます。
|
|
実行結果:
| name | price |
|---|---|
| ノートPC | 120000 |
| モニター | 55000 |
| デスク | 45000 |
| オフィスチェア | 35000 |
| 本棚 | 28000 |
OFFSETで取得開始位置を指定
OFFSET句と組み合わせることで、ページング処理を実装できます。
|
|
実行結果:
| name | price |
|---|---|
| ヘッドセット | 12000 |
| キーボード | 8000 |
| デスクライト | 6500 |
| マウス | 3500 |
| ペン(10本セット) | 500 |
ページング実装のパターン
Webアプリケーションでのページング実装では、以下の計算式を使用します。
|
|
なお、大量のデータに対してOFFSET値が大きくなるとパフォーマンスが低下します。その場合はカーソルベースのページングを検討してください。
集計関数の活用
基本的な集計関数
PostgreSQLで頻繁に使用する集計関数を紹介します。
| 関数 | 説明 | NULL値の扱い |
|---|---|---|
COUNT(*) |
行数をカウント | NULLを含む全行をカウント |
COUNT(column) |
指定カラムの非NULL値をカウント | NULLは除外 |
SUM(column) |
合計値を計算 | NULLは除外 |
AVG(column) |
平均値を計算 | NULLは除外 |
MAX(column) |
最大値を取得 | NULLは除外 |
MIN(column) |
最小値を取得 | NULLは除外 |
|
|
実行結果(3つ目のクエリ):
| total_price | avg_price | max_price | min_price |
|---|---|---|---|
| 313500 | 31350.00 | 120000 | 500 |
COUNTの使い分け
COUNT(*)とCOUNT(column)の違いを理解しておくことが重要です。
|
|
GROUP BYによるグループ化
基本的なグループ化
GROUP BY句を使用して、特定のカラムの値でグループ化し、グループごとの集計ができます。
|
|
実行結果:
| category | product_count |
|---|---|
| 電子機器 | 5 |
| 家具 | 3 |
| 照明 | 1 |
| 文具 | 1 |
|
|
実行結果:
| category | product_count | avg_price | total_stock |
|---|---|---|---|
| 電子機器 | 5 | 39700.00 | 330 |
| 家具 | 3 | 36000.00 | 40 |
| 照明 | 1 | 6500.00 | 60 |
| 文具 | 1 | 500.00 | 200 |
複数カラムでのグループ化
複数のカラムでグループ化することも可能です。
|
|
HAVING句によるグループのフィルタリング
GROUP BY後のグループに対して条件を指定する場合はHAVING句を使用します。WHERE句は行のフィルタリング、HAVING句はグループのフィルタリングという違いがあります。
|
|
実行結果:
| category | product_count |
|---|---|
| 電子機器 | 5 |
| 家具 | 3 |
|
|
WHEREとHAVINGの違い
|
|
DISTINCTによる重複排除
単一カラムの重複排除
DISTINCT句を使用して、重複する値を排除できます。
|
|
実行結果:
| category |
|---|
| 電子機器 |
| 家具 |
| 照明 |
| 文具 |
複数カラムの重複排除
複数カラムを指定した場合、全てのカラムの値の組み合わせが一致する行が重複とみなされます。
|
|
DISTINCT ONによる高度な重複排除
PostgreSQL独自の機能として、DISTINCT ONを使用すると、指定したカラムの値ごとに最初の1行のみを取得できます。
|
|
実行結果:
| category | name | price |
|---|---|---|
| 家具 | 本棚 | 28000 |
| 文具 | ペン(10本セット) | 500 |
| 照明 | デスクライト | 6500 |
| 電子機器 | マウス | 3500 |
DISTINCT ONを使用する場合、ORDER BY句の先頭はDISTINCT ONで指定したカラムと一致させる必要があります。
エイリアス(AS)の活用
カラムエイリアス
ASキーワードを使用して、カラムに別名を付けることができます。
|
|
実行結果:
| 商品名 | 価格 | 在庫数 | 在庫金額 |
|---|---|---|---|
| ノートPC | 120000 | 25 | 3000000 |
| マウス | 3500 | 150 | 525000 |
| … | … | … | … |
ASキーワードは省略可能ですが、可読性のために明示的に記述することを推奨します。
|
|
テーブルエイリアス
FROM句でテーブルに別名を付けることで、クエリを簡潔に記述できます。特に複数テーブルを結合する際に有効です。
|
|
計算式とエイリアス
集計関数や計算式の結果にエイリアスを付けると、結果の可読性が向上します。
|
|
実践的なクエリ例
売上分析クエリ
|
|
在庫アラートクエリ
|
|
日別集計クエリ
|
|
まとめ
本記事では、PostgreSQLにおけるSELECT文の基本から応用までを解説しました。
SELECT文を使いこなすためのポイントをまとめます。
| 機能 | 用途 | 主なキーワード |
|---|---|---|
| 基本的なデータ取得 | テーブルからカラムを選択 | SELECT, FROM |
| 条件指定 | 必要な行のみ抽出 | WHERE, AND, OR, IN, BETWEEN, LIKE |
| 並び替え | 結果の順序を制御 | ORDER BY, ASC, DESC |
| 件数制限 | ページングの実装 | LIMIT, OFFSET |
| 集計 | データの統計分析 | COUNT, SUM, AVG, MAX, MIN |
| グループ化 | カテゴリ別集計 | GROUP BY, HAVING |
| 重複排除 | ユニークな値の取得 | DISTINCT, DISTINCT ON |
| 別名付与 | 可読性の向上 | AS |
これらの機能を組み合わせることで、ほとんどのデータ取得要件に対応できます。次のステップとして、JOINを使った複数テーブルの結合やサブクエリについて学ぶことで、より複雑なデータ操作が可能になります。