SQLにおけるCASEステートメント
SQLにおけるCASEステートメントは、ほとんどのプログラミング言語で使われるif-then-elseの制御フローと似たような動作をします。これにより、SQLクエリ内で条件付きの論理を使用して、特定の値を返したり、特定の条件に基づいて異なる式を実行したりすることが可能になります。
例えば、SELECT文内でCASEステートメントを使用して、各行の列値に基づいてデータの表示を変更することができます。
CASEステートメントのタイプ: シンプルとサーチド
SQLには、シンプルなCASE式とサーチドなCASE式の2つのタイプがあります。
シンプルなCASE式
シンプルなCASE式は、結果を決定するために式を一連のシンプルな式と比較します。これは等価チェックのようなものです。
CASE expression
WHEN expression1 THEN result1
WHEN expression2 THEN result2
...
ELSE result
END;
以下はシンプルなCASEステートメントの例です。
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式は、結果を決定するために一連のブール式を評価します。これはブール論理を使用することと似ています。
CASE
WHEN condition1 THEN result1
WHEN condition2 THEN result2
...
ELSE result
END;
以下はサーチドなCASEステートメントの例です。
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ステートメントを使用する例です。
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ステートメントを使用する例です。
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の行のみを更新したい場合があります。
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値を置換する例です。
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値を平均値で置換する例です。
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の価格の平均値である平均価格を返します。それ以外の場合は、実際の価格を返します。