0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

PostgreSQL:CASE:条件によって返す値を変える方法

0
Last updated at Posted at 2026-10-11

今回はPostgreSQLのCASEを使い、条件によって返す値を変えます。取得したデータの意味を整理します。

所要時間は15分ほどです。
それでは、さっそく始めていきましょう!

用語と到達目標

CASEは、条件を上から順に確認し、最初にTRUEとなった条件に対応する値を返すSQLの式です。TRUEは、条件が成り立つことを表します。

CASE
    WHEN 条件 THEN 条件を満たした場合の値
    ELSE それ以外の場合の値
END
記述 役割
WHEN 判定する条件を書く
THEN その条件がTRUEの場合に返す値を書く
ELSE どのWHENもTRUEにならなかった場合の値を書く
END CASE式を終える

今回の目標は、NULLかどうかと日付の範囲を使って、表示する文字列を分けられることです。

今回使うデータ

取得元はmobility.poisです。1行が1施設を表します。

列名 意味
poi_id 施設を識別するID
poi_name 施設名
closed_date 閉業日を表す日付型の列

演習では、施設IDが1・39・41の3施設を使いました。

演習①:日付の有無で表示を分ける

次のSQLを実行しました。

SELECT
    poi_id,
    poi_name,
    closed_date,
    CASE
        WHEN closed_date IS NULL THEN '日付なし'
        ELSE '日付あり'
    END AS closed_date_status
FROM mobility.pois
WHERE poi_id IN (1, 39, 41)
ORDER BY poi_id;

実行結果は次の3行でした。

poi_id poi_name closed_date closed_date_status
1 Tokyo_station_001 NULL(画面では空欄) 日付なし
39 Omiya_hotel_039 2020-02-24 日付あり
41 Tokyo_station_041 2023-09-26 日付あり

closed_date IS NULLは、閉業日がNULLならTRUEになります。

ID1ではこの条件がTRUEなので、THENの「日付なし」が返ります。ID39・41ではNULLではないため、ELSEの「日付あり」が返ります。

「閉業日がNULLの施設では、THENとELSEのどちらの値が返るか」という確認には、「THEN」と回答しました。

表示する文字列の意味を限定する

ここでの「日付なし」「日付あり」は、列の値がNULLかどうかを表しています。営業中か、すでに閉業したかを判定するものではありません。

また、closed_date_statusはSELECTの結果に付けた列名です。テーブルに新しい列を追加する操作ではなく、保存された閉業日も変更していません。

演習②:WHENを増やして3種類に分ける

次に、NULLではない日付を、2023年1月1日より前か、それ以降かに分けました。

SELECT
    poi_id,
    closed_date,
    CASE
        WHEN closed_date IS NULL THEN '日付なし'
        WHEN closed_date < DATE '2023-01-01' THEN '2023年より前'
        ELSE '2023年以降'
    END AS closed_date_group
FROM mobility.pois
WHERE poi_id IN (1, 39, 41)
ORDER BY poi_id;

実行結果は次のとおりでした。

poi_id closed_date closed_date_group
1 NULL(画面では空欄) 日付なし
39 2020-02-24 2023年より前
41 2023-09-26 2023年以降

それぞれの行で、次のように判定されます。

  • ID1:最初のWHENがTRUEなので、「日付なし」
  • ID39:最初のWHENがFALSE、2番目がTRUEなので、「2023年より前」
  • ID41:どちらのWHENもFALSEなので、ELSEの「2023年以降」

CASEは、最初にTRUEになったWHENに対応する値を返します。

境界の日付を確認する

確認問題では、閉業日がちょうど2023年1月1日の場合を考え、「2023年以降」と回答しました。

2番目の条件は次の記述です。

closed_date < DATE '2023-01-01'

<は、指定した日付より前であることを判定します。同じ日付は含みません。

そのため2023年1月1日は、このWHENを満たさず、ELSEへ進みます。

この境界日の確認は、仮定した日付への回答です。画像で実際に取得した3施設に、2023年1月1日の行があったという意味ではありません。

NULLを先に分けた理由

今回のCASEでは、最初のWHENでNULLの行を分けています。

そのため、ELSEまで進むのは、日付が入力されていて、かつ2023年1月1日より前ではない行です。「2023年以降」というラベルが、その条件に対応します。

NULLを判定する最初のWHENを省くと、NULLと日付の比較はUNKNOWNとなり、日付のWHENは選ばれません。そのままELSEの「2023年以降」が返ると、日付不明の行を期間分類に混ぜてしまいます。

これは条件の意味を確認する説明であり、省略したSQLを追加実行したわけではありません。

CASEでTHENの値が返るのは、そのWHENがTRUEの場合です。FALSEやUNKNOWNの場合は、次のWHENやELSEへ進みます。

合格条件と学習記録

確認項目 確認できた内容
WHEN・THEN・ELSEを使う 日付の有無を3施設に表示
NULLの場合の分岐を説明する THENの値が返ると回答
複数のWHENを使う 日付なし・2023年より前・2023年以降に分類
境界の日付を判定する 2023年1月1日は2023年以降と回答

まとめ

CASEは上から順に条件を確認し、最初にTRUEになったWHENの値を返します。

今回のようにNULLを先に分けてから日付の範囲を判定すると、日付のない行と期間に属する行を区別できます。

表示用の分類名は、実際の条件に合わせて付けます。今回のSELECTは取得結果を作る操作であり、保存済みのデータを更新するものではありません。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?