Traffine I/O

日本語

2023-03-13

SQLにおけるCASEステートメント

SQLにおけるCASEステートメント

SQLにおけるCASEステートメントは、ほとんどのプログラミング言語で使われるif-then-elseの制御フローと似たような動作をします。これにより、SQLクエリ内で条件付きの論理を使用して、特定の値を返したり、特定の条件に基づいて異なる式を実行したりすることが可能になります。

例えば、SELECT文内でCASEステートメントを使用して、各行の列値に基づいてデータの表示を変更することができます。

CASEステートメントのタイプ: シンプルとサーチド

SQLには、シンプルなCASE式とサーチドなCASE式の2つのタイプがあります。

シンプルなCASE式

シンプルなCASE式は、結果を決定するために式を一連のシンプルな式と比較します。これは等価チェックのようなものです。

sql
CASE expression
    WHEN expression1 THEN result1
    WHEN expression2 THEN result2
    ...
    ELSE result
END;

以下はシンプルなCASEステートメントの例です。

sql
SELECT
    customer_id,
    CASE country
        WHEN 'USA' THEN 'Domestic'
        ELSE 'International'
    END AS customer_type
FROM customers;

このステートメントは、customersテーブル内の各行のcountry列をチェックします。もし国が「USA」であれば、「Domestic」を返します。それ以外の場合は、「International」を返します。新しい値はcustomer_typeという列に返されます。

サーチドなCASE式

サーチドなCASE式は、結果を決定するために一連のブール式を評価します。これはブール論理を使用することと似ています。

sql
CASE
    WHEN condition1 THEN result1
    WHEN condition2 THEN result2
    ...
    ELSE result
END;

以下はサーチドなCASEステートメントの例です。

sql
SELECT
    customer_id,
    CASE
        WHEN total_purchases > 10000 THEN 'Premium'
        WHEN total_purchases > 5000 THEN 'Gold'
        ELSE 'Regular'
    END AS customer_category
FROM customers;

このステートメントは、customersテーブル内の各行のtotal_purchases列をチェックします。もしtotal_purchasesが10,000より大きければ、「Premium」を返します。total_purchasesが5,000より大きい場合(ただし10,000を超えない場合)、「Gold」を返します。それ以外の場合は、「Regular」を返します。新しい値はcustomer_categoryという列に返されます。

なお、サーチドなCASE式では、条件は記述された順に評価されます。最初の条件(total_purchases > 10000)が真であれば、CASEステートメントは「Premium」を返し、次の条件(total_purchases > 5000)は評価されません。

ORDER BYでのCASEの使用

CASEステートメントをORDER BY句の内部で使用することで、SQLクエリの出力を条件に基づいて条件付きでソートすることができます。この強力な組み合わせにより、特定の基準に基づいてソート順を動的に制御することができます。

以下は、ORDER BY句内でCASEステートメントを使用する例です。

sql
SELECT
    customer_id,
    country,
    total_purchases
FROM
    customers
ORDER BY
    CASE
        WHEN country = 'USA' THEN total_purchases
        ELSE NULL
    END DESC;

この例では、CASEステートメントによって、USAの顧客を合計購入額の降順でソートしています。他の国の顧客はこのソートに含まれず、結果セットの最後にNULL値として表示されます(DESCの場合、NULL値は最後にソートされます)。

UPDATEでのCASEの使用

UPDATEステートメント内でCASEステートメントを使用すると、新しい値の設定に条件付きの論理を提供することができます。これは、新しい値が行内の既存の値または別の列の値に依存する場合に便利です。

以下は、UPDATEステートメント内でCASEステートメントを使用する例です。

sql
UPDATE
    customers
SET
    customer_category = CASE
        WHEN total_purchases > 10000 THEN 'Premium'
        WHEN total_purchases > 5000 THEN 'Gold'
        ELSE 'Regular'
    END;

この例では、CASEステートメントによって、各行のtotal_purchases列の値に基づいてcustomer_category列が更新されます。購入額が10,000を超える顧客は「Premium」として分類され、購入額が5,000を超えるが(ただし10,000を超えない)顧客は「Gold」となり、それ以外の顧客は「Regular」となります。

UPDATEステートメントでは、テーブル内の全ての行を更新したくない場合は、WHERE句を使用することを忘れずに記述する必要があります。例えば、customer_categoryがNULLの行のみを更新したい場合があります。

sql
UPDATE
    customers
SET
    customer_category = CASE
        WHEN total_purchases > 10000 THEN 'Premium'
        WHEN total_purchases > 5000 THEN 'Gold'
        ELSE 'Regular'
    END
WHERE
    customer_category IS NULL;

これにより、customer_category列の既存のデータを上書きすることが防止されます。上記のクエリでは、customer_categoryがNULLの行のみが更新されます。

CASEでのNULLの使用

CASEステートメントでは、NULLは他の値とは異なる扱いを受けます。NULL値を等価演算子(=や!=など)でテストすると、常にNULLまたは不明な値が返されます。NULLをチェックするには、WHEN条件の中でIS NULLおよびIS NOT NULL演算子を使用する必要があります。

さらに、WHEN句の条件がいずれも満たされず、ELSE句も存在しない場合、CASEステートメントはNULLを返します。

以下は、CASEステートメントを使用してNULL値を置換する例です。

sql
SELECT
    customer_id,
    CASE
        WHEN email IS NULL THEN 'Email not provided'
        ELSE email
    END AS email
FROM
    customers;

この例では、customersテーブル内の各行でemail列がNULLかどうかをチェックしています。もしNULLであれば、「Email not provided」を返します。それ以外の場合は、実際のメールアドレスを返します。

以下は、CASEステートメントを使用してNULL値を平均値で置換する例です。

sql
SELECT
    product_id,
    CASE
        WHEN price IS NULL THEN (SELECT AVG(price) FROM products WHERE price IS NOT NULL)
        ELSE price
    END AS price
FROM
    products;

この例では、productsテーブル内の各行でprice列がNULLかどうかをチェックしています。もしNULLであれば、非NULLの価格の平均値である平均価格を返します。それ以外の場合は、実際の価格を返します。

Ryusei Kakujo

researchgatelinkedingithub

Focusing on data science for mobility

Bench Press 100kg!