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