SQL Serverでは、T-SQL CASE expressionは、条件付きロジックに基づいて値を返すスカラー式です。条件のリストを評価し、それらの条件の結果に基づいて値を返します。
いくつかの点で、SQL Server CASE 式はIF...ELSEに似ています 。ただし、CASE IF...ELSEに対して、複数の条件をチェックできます しません。
また、SQL Serverでは、IF...ELSE は制御構造言語のキーワードですが、CASE ではありません。 CASE 式を使用して、T-SQLステートメント、ステートメントブロック、ユーザー定義関数、およびストアドプロシージャの実行フローを制御することはできません。
CASE式の2つの形式
CASEには2つの形式があります SQL Serverでの式:
- シンプルな
CASE表現 - 検索された
CASE表現
これらは以下の例で説明されています。
フォーム1–単純なCASE式
シンプルなCASE expressionは、式を一連の単純な式と比較して、結果を決定します。
CASEの基本的な例を次に示します。 式はSQLServerで機能します。
DECLARE @stock_ticker varchar(4) = 'V';
SELECT Company =
CASE @stock_ticker
WHEN 'AAPL' THEN 'Apple'
WHEN 'FB' THEN 'Facebook'
WHEN 'V' THEN 'Visa'
ELSE 'Not in the portfolio'
END 結果:
+-----------+ | Company | |-----------| | Visa | +-----------+
この例では、私のCASE 式はSELECTの一部です 声明。 3つの条件をチェックし、ELSEがあります 3つの条件でカバーされていないものに対応するため。
この場合、株式相場表示V 3番目のWHENと一致します 式、およびTHENによって提供される式 返されます。
明確にするために、実際のCASE 表現はこの部分です:
CASE @stock_ticker
WHEN 'AAPL' THEN 'Apple'
WHEN 'FB' THEN 'Facebook'
WHEN 'MA' THEN 'Mastercard'
WHEN 'V' THEN 'Visa'
ELSE 'Not in the portfolio'
END
CASEとは つまり、各WHENの値をチェックします 入力式に対する式。私の例では、@stock_ticker 変数は入力式です。したがって、各WHENの値をチェックします @stock_tickerに対する表現 変数。
一致するものが見つかると、THENによって提供される式を返します。 。
私の例では、3つのWHENを使用しています 式ですが、私の要件によっては、もっと多かったかもしれませんし、少なかったかもしれません。
フォーム2–検索されたCASE式
検索されたCASE expressionは、ブール式のセットを評価して結果を決定します。
検索されたCASEの例を次に示します。 表現。
DECLARE @price int = 1500;
SELECT Affordability =
CASE
WHEN @price < 100 THEN 'Cheap'
WHEN @price >= 100 AND @price < 500 THEN 'Affordable'
ELSE 'Expensive'
END 結果:
+-----------------+ | Affordability | |-----------------| | Expensive | +-----------------+
検索されたCASE 式には、単純なCASEのような入力式はありません。 表現。
簡単なCASEでそれを思い出してください 式、それはCASEで始まりました @stock_ticker 、したがって、WHEN 式はすべて、@stock_tickerの値に対して評価されていました。 。
検索されたCASE 式、そのような最初の入力式は提供しません。代わりに、各WHEN 式には、評価対象のブール式が含まれています。
データベースの例
これは、CASEがどのように行われるかを示す例です。 式はデータベースクエリ内で使用できます。
USE WideWorldImporters;
SELECT
CityName AS [City],
LatestRecordedPopulation AS [Population],
Size =
CASE
WHEN LatestRecordedPopulation < 2000000 THEN 'Small City'
WHEN LatestRecordedPopulation >= 2000000 AND LatestRecordedPopulation < 3000000 THEN 'Big City'
ELSE 'Really Big City'
END
FROM Application.Cities
WHERE LatestRecordedPopulation > 1000000; 結果:
+--------------+--------------+-----------------+ | City | Population | Size | |--------------+--------------+-----------------| | Brooklyn | 2565635 | Big City | | Chicago | 2695598 | Big City | | Dallas | 1197816 | Small City | | Houston | 2099451 | Big City | | Los Angeles | 3792621 | Really Big City | | Manhattan | 1619090 | Small City | | New York | 8175133 | Really Big City | | Philadelphia | 1526006 | Small City | | Phoenix | 1445632 | Small City | | Queens | 2272771 | Big City | | San Antonio | 1327407 | Small City | | San Diego | 1307402 | Small City | | The Bronx | 1408473 | Small City | +--------------+--------------+-----------------+
この例では、検索されたCASEを使用します LatestRecordedPopulationの結果を評価する式 Application.Citiesの列 テーブル。
データ型
SQL Serverでは、入力式のデータ型とWHEN 式は同じであるか、暗黙の変換である必要があります。
そうでない場合は、次のようになります。
DECLARE @stock_ticker varchar(4) = 'V';
SELECT Company =
CASE @stock_ticker
WHEN 1 THEN 'Apple'
WHEN 2 THEN 'Facebook'
WHEN 3 THEN 'Mastercard'
WHEN 4 THEN 'Visa'
ELSE 'Not in the portfolio'
END 結果:
Msg 245, Level 16, State 1, Line 3 Conversion failed when converting the varchar value 'V' to data type int.
評価の順序
T-SQLのCASE 式はその条件を順番に評価し、条件が満たされた最初の条件で停止します。
これを示すために、複数のWHENを使用してみましょう 同じ値を共有する式:
DECLARE @stock_ticker varchar(4) = 'V';
SELECT Company =
CASE @stock_ticker
WHEN 'V' THEN 'Visa 1'
WHEN 'V' THEN 'Visa 2'
WHEN 'V' THEN 'Visa 3'
ELSE 'Not in the portfolio'
END 結果:
+-----------+ | Company | |-----------| | Visa 1 | +-----------+
この場合、最初のWHENで停止しました 表現。
CASEの前に式が評価される場合があります。 式は、式の結果を入力として受け取ります。このようなシナリオでは、エラーが発生する可能性があります。これは、集計式をWHENとして含めると発生する可能性があります 表現。
このため、Microsoftは次のことをお勧めします。
集計式ではなく、スカラー式(スカラーを返す非相関サブクエリを含む)のWHEN条件の評価の順序のみに依存する必要があります。
ELSEはオプションです
ELSE 引数はオプションです。したがって、「手頃な価格」の例を次のように書き直すことができます。
DECLARE @price int = 1500;
SELECT Affordability =
CASE
WHEN @price < 100 THEN 'Cheap'
WHEN @price >= 100 AND @price < 500 THEN 'Affordable'
WHEN @price >= 500 THEN 'Expensive'
END 結果:
+-----------------+ | Affordability | |-----------------| | Expensive | +-----------------+
ただし、NULLになってしまう可能性があることに注意してください ELSEを省略した場合 口論。
次の例では、NULLになります。 :
DECLARE @price int = 1500;
SELECT Affordability =
CASE
WHEN @price < 100 THEN 'Cheap'
WHEN @price >= 100 AND @price < 500 THEN 'Affordable'
WHEN @price >= 500 AND @price < 1000 THEN 'Expensive'
END 結果:
+-----------------+ | Affordability | |-----------------| | NULL | +-----------------+
このような場合、いつでもELSEを追加できます。 念のため、議論(駄洒落について申し訳ありません!):
DECLARE @price int = 1500;
SELECT Affordability =
CASE
WHEN @price < 100 THEN 'Cheap'
WHEN @price >= 100 AND @price < 500 THEN 'Affordable'
WHEN @price >= 500 AND @price < 1000 THEN 'Expensive'
ELSE 'Unknown'
END 結果:
+-----------------+ | Affordability | |-----------------| | Unknown | +-----------------+
確かに、この例はおそらく少し工夫されています。結局のところ、「高価」を制限する必要はありません。何かが1000ドル未満で高価な場合、1000ドルを超えると、それも高価になります。
ただし、要点は、ELSEを使用できるということです。 WHENでカバーされていないものをキャッチする 式/秒。
ネストされたCASE式
CASEをネストできます 必要に応じて式。
DECLARE @price int, @on_sale bit;
SET @price = 1500;
SET @on_sale = 1;
SELECT Affordability =
CASE
WHEN @price < 100 THEN 'Cheap'
WHEN @price >= 100 THEN
CASE @on_sale
WHEN 0 THEN 'Expensive (but it''s not currently on sale)'
WHEN 1 THEN 'Expensive (and it''s already on sale!)'
END
END 結果:
+---------------------------------------+ | Affordability | |---------------------------------------| | Expensive (and it's already on sale!) | +---------------------------------------+
ただし、CASEでは10レベルのネストのみが許可されていることに注意してください。 SQLServerの式。 10レベルを超えてネストしようとすると、エラーが発生します。
ORDERBY句のケース
前述のように、T-SQLのCASE 式は、有効な式を許可する任意のステートメントまたは句で使用できます。したがって、SELECTなどのステートメントで使用できます。 、UPDATE 、DELETE およびSET 、およびINなどの句 、WHERE 、ORDER BY 、GROUP BY 、およびHAVING 。
CASEの使用 ステートメントのORDER BYの式 結果を並べ替えるときに特定の値に対して特別な例外を作成する場合は、句が便利です。
音楽のジャンルを含むテーブルに対して次のクエリを実行するとします。
SELECT Genre
FROM MusicGenres
ORDER BY Genre ASC; 結果:
+---------+ | Genre | |---------| | Blues | | Country | | Hip Hop | | Jazz | | Metal | | Other | | Pop | | Rap | | Rock | +---------+
ここでは、結果をGenreで並べ替えています。 列、昇順。
これは1つを除いて問題ありません。 その他というジャンル 。 その他を移動できたら素晴らしいと思いませんか 一番下まで?
これは、CASEで実現できます。 上記のクエリを取得し、次のように変更して式を作成します。
SELECT Genre
FROM MusicGenres
ORDER BY
CASE Genre
WHEN 'Other' THEN 1
ELSE 0
END
ASC, Genre ASC; 結果:
+---------+ | Genre | |---------| | Blues | | Country | | Hip Hop | | Jazz | | Metal | | Pop | | Rap | | Rock | | Other | +---------+
UPDATEステートメントのケース
CASEの使用例を次に示します。 UPDATEの式 ステートメント。
次の表があるとします。
+---------+-----------+-----------+----------+ | DogId | DogName | GoodDog | Dinner | |---------+-----------+-----------+----------| | 1 | Fetch | 1 | NULL | | 2 | Fluffy | 0 | NULL | | 3 | Wag | 0 | NULL | | 1001 | Brian | 1 | NULL | | 1002 | Rambo | 0 | NULL | | 1003 | BamBam | 1 | NULL | +---------+-----------+-----------+----------+
最近、Dinnerを追加しました 列であり、まだNULL 、値が挿入されるのを待っています。
ただし、挿入される値は、GoodDogの値によって異なります。 桁。
CASEを使用できます そのようなシナリオでの表現。
UPDATE Dogs
SET Dinner =
CASE GoodDog
WHEN 1 THEN 'Sunday Roast'
ELSE 'Airline food'
END
SELECT * FROM Dogs; 結果:
+---------+-----------+-----------+--------------+ | DogId | DogName | GoodDog | Dinner | |---------+-----------+-----------+--------------| | 1 | Fetch | 1 | Sunday Roast | | 2 | Fluffy | 0 | Airline food | | 3 | Wag | 0 | Airline food | | 1001 | Brian | 1 | Sunday Roast | | 1002 | Rambo | 0 | Airline food | | 1003 | BamBam | 1 | Sunday Roast | +---------+-----------+-----------+--------------+
INSERTステートメントのケース
上記の例から表を取得して、新しい値を挿入できます。
また、CASEを再び利用できます Dinnerに適切な値を挿入する式 列。
DECLARE @DogName nvarchar(60), @GoodDog bit;
SET @DogName = 'Lazy';
SET @GoodDog = 0;
INSERT INTO Dogs ( DogName, GoodDog, Dinner )
VALUES (
@DogName,
@GoodDog,
CASE @GoodDog
WHEN 1 THEN 'Sunday Roast'
ELSE 'Airline food'
END
);
SELECT * FROM Dogs; 結果:
+---------+-----------+-----------+--------------+ | DogId | DogName | GoodDog | Dinner | |---------+-----------+-----------+--------------| | 1 | Fetch | 1 | Sunday Roast | | 2 | Fluffy | 0 | Airline food | | 3 | Wag | 0 | Airline food | | 1001 | Brian | 1 | Sunday Roast | | 1002 | Rambo | 0 | Airline food | | 1003 | BamBam | 1 | Sunday Roast | | 1004 | Lazy | 0 | Airline food | +---------+-----------+-----------+--------------+
今回はCASE 式は、設定したばかりの変数の値を評価し、適切な値をDinnerに挿入していました。 列。
それはCASEステートメントですか、それともCASE式ですか?
SQLでは、実際には別のものであるにもかかわらず、多くのものが「ステートメント」と呼ばれます。これは、T-SQLの「CASE」にも当てはまるようです。 ステートメント」。
CASEと呼ばれることもありますが ステートメント、それをCASEと呼ぶ方が正確です 式 。これは、Microsoftのドキュメントがそれを参照する方法でもあります。
SQL Serverでは、ステートメント自体ではなく、CASE 有効な式を許可する任意のステートメントまたは句で使用できます。式は、単一のデータ値を取得するために評価される記号と演算子の組み合わせです。
ただし、一部のDBMSはCASEを区別します ステートメント、およびCASE 式、およびそれぞれにわずかに異なる構文があります。 MySQLはCASEを区別します ステートメントとCASE 演算子。これは基本的にCASEと同じです。 表現。