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
と同じです。 表現。