sql >> データベース >  >> RDS >> Mysql

SQLCASEステートメント

    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などのステートメントで使用できます。 、UPDATEDELETE およびSET 、およびINなどの句 、WHEREORDER BYGROUP 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

    1. 後続ゼロ

    2. PSQLスクリプト(bashスクリプトから供給)の変数として外部XMLファイルにアクセスする

    3. PHPを使用する場合のMySQLとMySQLi

    4. SQLServerで英数字以外の文字を含む行を返す