SQLでは、CASE ステートメントは条件のリストを評価し、複数の可能な結果式の1つを返します。
いくつかの点で、SQL CASE ステートメントは、IF...ELSEに似ています。 特定の条件をチェックし、結果に応じて異なる結果を返すことができるという点でステートメント。
それはCASEですか ステートメントまたはCASE 表現?
SQLでは、実際には別のものであるにもかかわらず、「ステートメント」と呼ばれることがあります。 SQL「CASE 「ステートメント」はその好例です(駄洒落については申し訳ありません!)。
CASE ステートメントは、SQL標準(ISO / IEC 9075)ではCASEと呼ばれています。 式 。その目的は「条件値を指定する」ことです。
ただし、一部のDBMSはCASEを区別します ステートメントとCASE 式、およびそれぞれにわずかに異なる構文があります。たとえば、MySQLとMariaDBの両方がCASEを提供します ステートメントとCASE 演算子は2つの異なる機能であり、それぞれ構文がわずかに異なります。
CASE フォーマット
SQLには、CASEの2つの形式があります 式:
- シンプルな
CASE表現 - 検索された
CASE表現
以下はそれぞれの例です。
シンプルなCASE 式
シンプルなCASE expressionは、式を一連の単純な式と比較して、結果を決定します。
例:
DECLARE @animal VARCHAR(40);
SET @animal = 'Cow';
SELECT
CASE @animal
WHEN 'Bird' THEN 'Seed'
WHEN 'Dog' THEN 'Beef'
WHEN 'Cow' THEN 'Grass'
ELSE 'Leftovers'
END; 結果:
Grass
この例はMySQLで実行されましたが、実際のCASE 式は、ほとんどの主要なRDBMSで機能するはずです。
この例では、私のCASE 式はSELECTの一部です 声明。 3つの条件をチェックし、ELSEがあります 3つの条件でカバーされていないものに対応するため。
この場合、動物のCow 3番目のWHENと一致します 式、およびそのTHENによって提供される式 返されます。
明確にするために、実際のCASE 表現はこの部分です:
CASE @animal
WHEN 'Bird' THEN 'Seed'
WHEN 'Dog' THEN 'Beef'
WHEN 'Cow' THEN 'Grass'
ELSE 'Leftovers'
END
CASEとは 各WHENの値を確認します 入力式に対する式。この例では、@animal 変数は入力式です。したがって、各WHENの値をチェックします @animalに対する表現 変数。
一致するものが見つかると、対応するTHENによって提供される式を返します。 。
私の例では、3つのWHENを使用しています 式が、要件に応じて、より多く使用することも、より少なく使用することもできました。
検索されたCASE 式
検索されたCASE expressionは、ブール式のセットを評価して結果を決定します。
検索されたCASEの例を次に示します。 表現。
DECLARE @score int;
SET @score = 7;
SELECT
CASE
WHEN @score > 8 THEN 'Congratulations!'
WHEN @score > 5 AND @score < 8 THEN 'Well done!'
ELSE 'Try harder next time'
END; 結果:
Well done!
検索されたCASE 式には、単純なCASEのような入力式はありません。 表現。
簡単なCASEでそれを思い出してください 式、それはCASEで始まりました @animal 、したがって、WHEN 式はすべて@animalの値に対して評価されていました 。
検索されたCASE 式、そのような最初の入力式は提供しません。代わりに、各WHEN 式には、評価対象のブール式が含まれています。
データベースの例
これは、CASEがどのように行われるかを示す例です。 式はデータベースクエリ内で使用できます。
USE World;
SELECT
Name,
Population,
CASE
WHEN Population > 2000000 THEN 'Huge City'
WHEN Population >= 1000000 AND Population < 2000000 THEN 'Big City'
ELSE 'Small City'
END AS Size
FROM City
WHERE CountryCode = 'USA'
ORDER BY Population DESC
LIMIT 20; 結果:
+---------------+------------+------------+ | Name | Population | Size | +---------------+------------+------------+ | New York | 8008278 | Huge City | | Los Angeles | 3694820 | Huge City | | Chicago | 2896016 | Huge City | | Houston | 1953631 | Big City | | Philadelphia | 1517550 | Big City | | Phoenix | 1321045 | Big City | | San Diego | 1223400 | Big City | | Dallas | 1188580 | Big City | | San Antonio | 1144646 | Big City | | Detroit | 951270 | Small City | | San Jose | 894943 | Small City | | Indianapolis | 791926 | Small City | | San Francisco | 776733 | Small City | | Jacksonville | 735167 | Small City | | Columbus | 711470 | Small City | | Austin | 656562 | Small City | | Baltimore | 651154 | Small City | | Memphis | 650100 | Small City | | Milwaukee | 596974 | Small City | | Boston | 589141 | Small City | +---------------+------------+------------+
この例では、検索されたCASEを使用します Populationの結果を評価する式 Cityの列 テーブル。
ELSE オプションです
ELSE 引数はオプションです。 ELSEを省略した場合 、およびどの条件もトリガーされない場合、結果はNULLになります 。
ELSEを省略した場合は次のようになります 前の例の句:
USE World;
SELECT
Name,
Population,
CASE
WHEN Population > 2000000 THEN 'Huge City'
WHEN Population >= 1000000 AND Population < 2000000 THEN 'Big City'
END AS Size
FROM City
WHERE CountryCode = 'USA'
ORDER BY Population DESC
LIMIT 20; 結果:
+---------------+------------+-----------+ | Name | Population | Size | +---------------+------------+-----------+ | New York | 8008278 | Huge City | | Los Angeles | 3694820 | Huge City | | Chicago | 2896016 | Huge City | | Houston | 1953631 | Big City | | Philadelphia | 1517550 | Big City | | Phoenix | 1321045 | Big City | | San Diego | 1223400 | Big City | | Dallas | 1188580 | Big City | | San Antonio | 1144646 | Big City | | Detroit | 951270 | NULL | | San Jose | 894943 | NULL | | Indianapolis | 791926 | NULL | | San Francisco | 776733 | NULL | | Jacksonville | 735167 | NULL | | Columbus | 711470 | NULL | | Austin | 656562 | NULL | | Baltimore | 651154 | NULL | | Memphis | 650100 | NULL | | Milwaukee | 596974 | NULL | | Boston | 589141 | NULL | +---------------+------------+-----------+
CASE UPDATEで ステートメント
Cityに列を追加しましょう 前の例の表:
ALTER TABLE City
ADD COLUMN Size VARCHAR(30) AFTER Population;
SELECT * FROM City
LIMIT 10; 現在の状況は次のとおりです。
+----+----------------+-------------+---------------+------------+------+ | ID | Name | CountryCode | District | Population | Size | +----+----------------+-------------+---------------+------------+------+ | 1 | Kabul | AFG | Kabol | 1780000 | NULL | | 2 | Qandahar | AFG | Qandahar | 237500 | NULL | | 3 | Herat | AFG | Herat | 186800 | NULL | | 4 | Mazar-e-Sharif | AFG | Balkh | 127800 | NULL | | 5 | Amsterdam | NLD | Noord-Holland | 731200 | NULL | | 6 | Rotterdam | NLD | Zuid-Holland | 593321 | NULL | | 7 | Haag | NLD | Zuid-Holland | 440900 | NULL | | 8 | Utrecht | NLD | Utrecht | 234323 | NULL | | 9 | Eindhoven | NLD | Noord-Brabant | 201843 | NULL | | 10 | Tilburg | NLD | Noord-Brabant | 193238 | NULL | +----+----------------+-------------+---------------+------------+------+
新しいSizeにはデータを挿入していません 列なので、NULLを返します すべての行で。
これで、CASEを使用できます Sizeを更新する式 Populationの値に依存する値を持つ列 列:
UPDATE City
SET Size =
CASE
WHEN Population > 2000000 THEN 'Huge City'
WHEN Population >= 1000000 AND Population < 2000000 THEN 'Big City'
ELSE 'Small City'
END; 次に、テーブルからデータを選択しましょう:
SELECT * FROM City
WHERE CountryCode = 'USA'
ORDER BY Population DESC
LIMIT 20; 結果:
+------+---------------+-------------+---------------+------------+------------+ | ID | Name | CountryCode | District | Population | Size | +------+---------------+-------------+---------------+------------+------------+ | 3793 | New York | USA | New York | 8008278 | Huge City | | 3794 | Los Angeles | USA | California | 3694820 | Huge City | | 3795 | Chicago | USA | Illinois | 2896016 | Huge City | | 3796 | Houston | USA | Texas | 1953631 | Big City | | 3797 | Philadelphia | USA | Pennsylvania | 1517550 | Big City | | 3798 | Phoenix | USA | Arizona | 1321045 | Big City | | 3799 | San Diego | USA | California | 1223400 | Big City | | 3800 | Dallas | USA | Texas | 1188580 | Big City | | 3801 | San Antonio | USA | Texas | 1144646 | Big City | | 3802 | Detroit | USA | Michigan | 951270 | Small City | | 3803 | San Jose | USA | California | 894943 | Small City | | 3804 | Indianapolis | USA | Indiana | 791926 | Small City | | 3805 | San Francisco | USA | California | 776733 | Small City | | 3806 | Jacksonville | USA | Florida | 735167 | Small City | | 3807 | Columbus | USA | Ohio | 711470 | Small City | | 3808 | Austin | USA | Texas | 656562 | Small City | | 3809 | Baltimore | USA | Maryland | 651154 | Small City | | 3810 | Memphis | USA | Tennessee | 650100 | Small City | | 3811 | Milwaukee | USA | Wisconsin | 596974 | Small City | | 3812 | Boston | USA | Massachusetts | 589141 | Small City | +------+---------------+-------------+---------------+------------+------------+
CASE INSERTで ステートメント
SQLServerデータベースに次のテーブルがあるとします。
+---------+-----------+-----------+--------------+ | DogId | DogName | GoodDog | Dinner | |---------+-----------+-----------+--------------| | 1001 | Brian | 1 | Sunday Roast | | 1002 | Rambo | 0 | Airline food | | 1003 | BamBam | 1 | Sunday Roast | +---------+-----------+-----------+--------------+
そのテーブルに新しい行を挿入しましょう。ただし、CASEを使用しましょう Dinnerに適切な値を挿入する式 GoodDogの値に応じて列 列:
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
);
ここでは、CASE 式は、設定したばかりの変数の値を評価し、適切な値をDinnerに挿入しました。 列。
次に、テーブルをもう一度確認しましょう:
SELECT * FROM Dogs; 結果:
+---------+-----------+-----------+--------------+ | DogId | DogName | GoodDog | Dinner | |---------+-----------+-----------+--------------| | 1001 | Brian | 1 | Sunday Roast | | 1002 | Rambo | 0 | Airline food | | 1003 | BamBam | 1 | Sunday Roast | | 1004 | Lazy | 0 | Airline food | +---------+-----------+-----------+--------------+
Dinnerに適切な値があることがわかります 列。
CASE ORDER BYで 条項
CASE 式は、有効な式を許可する任意のステートメントまたは句で使用できます。したがって、SELECTなどのステートメントで使用できます。 、UPDATE 、DELETE およびSET 、およびINなどの句 、WHERE 、ORDER BY 、GROUP BY 、およびHAVING 。
CASEの使用 ステートメントのORDER BYの式 結果を並べ替えるときに特定の値に対して特別な例外を作成する場合は、句が便利です。
音楽のジャンルを含むテーブルに対して次のクエリを実行するとします。
SELECT Genre
FROM Genres
ORDER BY Genre ASC; 結果:
+---------+ | Genre | +---------+ | Blues | | Country | | Hip Hop | | Jazz | | Other | | Pop | | Punk | | Rap | | Rock | +---------+
ここでは、結果をGenreで並べ替えています。 列、昇順。
これは1つを除いて問題ありません。 Otherと呼ばれるジャンル 。 Otherを移動できたら素晴らしいと思いませんか 一番下まで?
これは、CASEで実現できます。 上記のクエリを取得し、次のように変更して式を作成します。
SELECT Genre
FROM Genres
ORDER BY
CASE Genre
WHEN 'Other' THEN 1
ELSE 0
END
ASC, Genre ASC; 結果:
+---------+ | Genre | +---------+ | Blues | | Country | | Hip Hop | | Jazz | | Pop | | Punk | | Rap | | Rock | | Other | +---------+
COALESCE() およびNULLIF() 機能
シナリオに応じて、COALESCE()などの関数を使用できます。 およびNULLIF() CASEを使用する代わりに、ショートカットとして 表現。
これらの2つの関数はSQL標準であり、次のように機能します。
NULLIF (V1, V2) と同等です:
CASE WHEN V1=V2 THEN NULL ELSE V1 END そして:
COALESCE (V1, V2) と同等です:
CASE WHEN V1 IS NOT NULL THEN V1 ELSE V2 END また:
COALESCE (V1, V2, ..., Vn) と同等です:
CASE WHEN V1 IS NOT NULL THEN V1 ELSE COALESCE (V2, ..., Vn) END