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

SQLServerのCASE式

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


    1. JDBCインターフェースを介してUTF-8文字列をMySQLに正しく書き込む方法

    2. Mysqlクエリの結果をExcelにエクスポートしますか?

    3. Include()を何度も使用すると、Entity-Frameworkコードが遅くなります

    4. Postgresがインデックスを使用しないのはなぜですか?