SQL SELECTでIF…THENを実行するにはどうすればよいですか?


1508

ステートメントIF...THENでどのように実行しSQL SELECTますか?

例えば:

SELECT IF(Obsolete = 'N' OR InStock = 'Y' ? 1 : 0) AS Saleable, * FROM Product

14
このリンクをご覧になることをお勧めします。に関して:SQL WHERE句:CASEを避け、ブール論理を使用
誰かが

3
@Somebody:論理的な書き換えルールを使用して含意を分離に変換することについて記事が説明しているため、あまり関係ありません。手がかりは「論理的」という言葉、つまりtrueまたはfalseに解決されるもので、投影には適用されません。TL; DRの記事はに適用されますがWHERE、適用されCHECKませんSELECT
onedaywhen

6
@MartinSmithの答えは最もエレガントです。SQL2012+でIIFを使用してください。
マレーフォックスクロフト2017年

回答:


1760

CASE文は、SQLでIFに最も近いとSQL Serverのすべてのバージョンでサポートされています。

SELECT CAST(
             CASE
                  WHEN Obsolete = 'N' or InStock = 'Y'
                     THEN 1
                  ELSE 0
             END AS bit) as Saleable, *
FROM Product

CASTブール値として結果が必要な場合にのみ実行する必要があります。に満足しているint場合、これは機能します:

SELECT CASE
            WHEN Obsolete = 'N' or InStock = 'Y'
               THEN 1
               ELSE 0
       END as Saleable, *
FROM Product

CASEステートメントは他のCASEステートメントに埋め込むことも、集計に含めることもできます。

SQL Server Denali(SQL Server 2012)は、アクセスで使用可能なIIFステートメントを追加しますMartin Smithによって指摘されました)。

SELECT IIF(Obsolete = 'N' or InStock = 'Y', 1, 0) as Saleable, * FROM Product

57
ケースを使用するときは、追加の注意が必要です。それを実現するためにかなりの時間を取った:)
Archan Mishra

17
ENDを忘れないでください
Simon_Weaver 2014年

8
そしてASビット!
Cas Bloem 14

8
Case、When、ElseとEndは(同じ行に沿って)平行にインデントする必要があります-そして、それからさらに内側にインデントする必要があります-私にとって最適です。
Ujjwal Singh 2014

6
@ReeveStrifeのみiif SQL Server 2012+
stuartdotnet

327

ケースステートメントは、この状況での友であり、次の2つの形式のいずれかになります。

単純なケース:

SELECT CASE <variable> WHEN <value>      THEN <returnvalue>
                       WHEN <othervalue> THEN <returnthis>
                                         ELSE <returndefaultcase>
       END AS <newcolumnname>
FROM <table>

拡張ケース:

SELECT CASE WHEN <test>      THEN <returnvalue>
            WHEN <othertest> THEN <returnthis>
                             ELSE <returndefaultcase>
       END AS <newcolumnname>
FROM <table>

caseステートメントをorder by句に入れて、非常に洗練された順序にすることもできます。


32
私はこれが古いことを知っていますが、結果の列に名前を付けるためにのAS Col_Name後にENDを追加できることに注意してください
Ben

9
私はいつも2番目のほうが簡単だと感じています。
Hogan

4
同意します。テストしたい条件は、1つの変数自体よりも常に複雑なので、ほとんどの場合、拡張Caseステートメントを使用します。また、読みやすくなっただけです。
magnum_pi 2016年

1
変数の有無にかかわらず、両方の状況についての適切な説明。変数を使用する場合、条件は、caseステートメントの後の変数と、条件の基準となる変数との間の等価性を満たしている必要があります。変数なしで、自己完結型の条件を追加してテストできます。
Remus.A

2番目のオプションの方が便利です。2つは同様に元気です。
Stanley Okpala Nwosa、2018年

277

SQL Server 2012以降では、このIIF機能を使用できます。

SELECT IIF(Obsolete = 'N' OR InStock = 'Y', 1, 0) AS Salable, *
FROM   Product

これは、実質的には(標準SQLではありませんが)省略形の記述方法ですCASE

拡張CASEバージョンと比較すると、簡潔さを好みます。

どちらIIF()CASESQLステートメント内の表現としての決意とだけ明確に定義された場所で使用することができます。

CASE式を使用して、Transact-SQLステートメント、ステートメントブロック、ユーザー定義関数、およびストアドプロシージャの実行フローを制御することはできません。

これらの制限(たとえば、条件に応じて異なる形状の結果セットを返す必要がある)でニーズを満たせない場合は、SQL Serverにも手続き型IFキーワードがあります。

IF @IncludeExtendedInformation = 1
  BEGIN
      SELECT A,B,C,X,Y,Z
      FROM   T
  END
ELSE
  BEGIN
      SELECT A,B,C
      FROM   T
  END

ただし、このアプローチでは、パラメータスニッフィングの問題を回避するように注意が必要な場合があります


6
SQLでIF .. thenステートメントが必要な場合は、これが答えになるはずです。
Mr.J 2017年

91

The Power of SQL CASE Statementsでいくつかの素晴らしい例を見つけることができます。私が使用できるステートメントは次のようなものになると思います(4guysfromrollaから):

SELECT
    FirstName, LastName,
    Salary, DOB,
    CASE Gender
        WHEN 'M' THEN 'Male'
        WHEN 'F' THEN 'Female'
    END
FROM Employees

4
興味深い議論についてはmeta.stackexchange.com/questions/103053/…を参照してください。私が提供する2つのリンクは、私がサポートする追加のコンテキストを追加します。
Sam Saffron、2011

2
参照は本当に役立つ
ので

75

使用事例。このようなもの。

SELECT Salable =
        CASE Obsolete
        WHEN 'N' THEN 1
        ELSE 0
    END


48

Microsoft SQL Server(T-SQL)

select、次を使用します:

select case when Obsolete = 'N' or InStock = 'Y' then 'YES' else 'NO' end

where句、使用します。

where 1 = case when Obsolete = 'N' or InStock = 'Y' then 1 else 0 end

1
なぜあなたはwhere Obsolete = 'N' or InStock = 'Y'実際に半分を半分にカットしないのですか
maksymiuk

46

このリンクからIF THEN ELSE、T-SQLで理解できます。

IF EXISTS(SELECT *
          FROM   Northwind.dbo.Customers
          WHERE  CustomerId = 'ALFKI')
  PRINT 'Need to update Customer Record ALFKI'
ELSE
  PRINT 'Need to add Customer Record ALFKI'

IF EXISTS(SELECT *
          FROM   Northwind.dbo.Customers
          WHERE  CustomerId = 'LARSE')
  PRINT 'Need to update Customer Record LARSE'
ELSE
  PRINT 'Need to add Customer Record LARSE' 

T-SQLにはこれで十分ではありませんか?


3
これはリクエスターが望んだものではありませんが、selectステートメントの外で ifステートメントを使用できることを知るのに非常に役立ちます。
ジョナサン

2
EXISTSは、アイテムが見つかると検索ループから外れるため、優れています。COUNTは、テーブル行の終わりまで実行されます。質問とは関係ありませんが、知っておくべきことです。
JustJohn 2016


32

SQL Serverの単純なif-elseステートメント:

DECLARE @val INT;
SET @val = 15;

IF @val < 25
PRINT 'Hi Ravi Anand';
ELSE
PRINT 'By Ravi Anand.';

GO

SQL ServerのネストされたIf ... elseステートメント-

DECLARE @val INT;
SET @val = 15;

IF @val < 25
PRINT 'Hi Ravi Anand.';
ELSE
BEGIN
IF @val < 50
  PRINT 'what''s up?';
ELSE
  PRINT 'Bye Ravi Anand.';
END;

GO

2
遅いですがSELECT、OPが尋ねたように内部で使用できますか?
abdul qayyum

25

新しい機能であるIIF(簡単に使用できる)がSQL Server 2012に追加されました。

SELECT IIF ( (Obsolete = 'N' OR InStock = 'Y'), 1, 0) AS Saleable, * FROM Product

1
この回答は数年前にMartin Smithによって回答ですでに提供されていた内容を(詳細は控えめに)繰り返しています。
jk7 2018年

1
@ jk7これが質問に対する最初の回答でした。
Sandeep Rawat

3
私が見るものからではありません。それはあなたの答えが16年4月26日に投稿され、マーティンは11年7月20日に投稿されたと言います。
jk7

24

CASEステートメントを使用します。

SELECT CASE
       WHEN (Obsolete = 'N' OR InStock = 'Y')
       THEN 'Y'
       ELSE 'N'
END as Available

etc...

23

純粋なビットロジックを使用します。

DECLARE @Product TABLE (
    id INT PRIMARY KEY IDENTITY NOT NULL
   ,Obsolote CHAR(1)
   ,Instock CHAR(1)
)

INSERT INTO @Product ([Obsolote], [Instock])
    VALUES ('N', 'N'), ('N', 'Y'), ('Y', 'Y'), ('Y', 'N')

;
WITH cte
AS
(
    SELECT
        'CheckIfInstock' = CAST(ISNULL(NULLIF(ISNULL(NULLIF(p.[Instock], 'Y'), 1), 'N'), 0) AS BIT)
       ,'CheckIfObsolote' = CAST(ISNULL(NULLIF(ISNULL(NULLIF(p.[Obsolote], 'N'), 0), 'Y'), 1) AS BIT)
       ,*
    FROM
        @Product AS p
)
SELECT
    'Salable' = c.[CheckIfInstock] & ~c.[CheckIfObsolote]
   ,*
FROM
    [cte] c

参照せずに、その後の場合:作業のデモをcaseSQL Serverで

スタートのために、あなたはの価値アウト作業する必要があるtruefalse選択された条件を。ここに2つのNULLIFがあります:

for true: ISNULL(NULLIF(p.[Instock], 'Y'), 1)
for false: ISNULL(NULLIF(p.[Instock], 'N'), 0)

一緒に結合すると1または0が得られます。次に、ビット演算子を使用します。

これは最もWYSIWYGの方法です。


19
コード難読化の場合は-1。真剣に、これはあなたが得ることができる限りWYSIWYGから遠いです!血色の悪い読めない混乱、そして私があなたのコードで作業しなければならなかったら、私は一日中悪態をつくでしょう...ごめんなさい:-/
Heliac

2
@Heliacはビューにcte部分を配置し、混乱を決して見ないでしょう。長くて複雑なAND、ORの場合、CASEよりも読みやすくはありません(もちろんcteの外側の部分)。
Tomasito 2013年

1
一度cteに入ると、これにきちんとした+1を与えましたが、現在のところ、質問に対する答えは間違っています。'|'が必要です 「&」ではありません。
Mark Hurd、2016年

3
@Heliacに完全に同意します。構文的には正しく、正常に動作しますが、簡単にはサポートできません。それをCTEに配置すると、読み取り不能なコードの一部が別の場所に移動します。
objectNotFound 2017年

1
組み合わせをチェックするテーブル方式には、その利点があります。テーブル変数を使用して既存のクエリに結合すると、ケースなしでセットベースのソリューションを提供できます。この答えは悪い例ですが、テーブルのアイデア自体にメリットがあります。
Suncat2000 2018年

19
SELECT 1 AS Saleable, *
  FROM @Product
 WHERE ( Obsolete = 'N' OR InStock = 'Y' )
UNION
SELECT 0 AS Saleable, *
  FROM @Product
 WHERE NOT ( Obsolete = 'N' OR InStock = 'Y' )


14
case statement some what similar to if in SQL server

SELECT CASE 
            WHEN Obsolete = 'N' or InStock = 'Y' 
               THEN 1 
               ELSE 0 
       END as Saleable, * 
FROM Product

2
これが質問の答えになる方法について説明してください。
Guanxi

@Guanxi:私の答えではありませんが、「ケース」は「if-then-else」を一般化します(2ケースから多数)
JosephDoggie

詳しく説明できますか?
Peter Mortensen

13

これは答えではなく、私が働いている場所で使用されているCASEステートメントの例にすぎません。ネストされたCASEステートメントがあります。私の目が交差する理由がわかります。

 CASE orweb2.dbo.Inventory.RegulatingAgencyName
    WHEN 'Region 1'
        THEN orweb2.dbo.CountyStateAgContactInfo.ContactState
    WHEN 'Region 2'
        THEN orweb2.dbo.CountyStateAgContactInfo.ContactState
    WHEN 'Region 3'
        THEN orweb2.dbo.CountyStateAgContactInfo.ContactState
    WHEN 'DEPT OF AGRICULTURE'
        THEN orweb2.dbo.CountyStateAgContactInfo.ContactAg
    ELSE (
            CASE orweb2.dbo.CountyStateAgContactInfo.IsContract
                WHEN 1
                    THEN orweb2.dbo.CountyStateAgContactInfo.ContactCounty
                ELSE orweb2.dbo.CountyStateAgContactInfo.ContactState
                END
            )
    END AS [County Contact Name]

1
Caseステートメントを再フォーマットした編集はすべて問題がなく、面白​​くて理解しやすくなっていますが、SQLはまだそれを使用しているビューに含まれています。
JustJohn 2016年

1
このように答えるべきCASEだったのIFではなく、なぜ賛成投票されて答えとしてマークされるのかをたださまよっています。このように、これはまだCASEステートメントではなく、IFです。
Mr.J 2017年

@ Jr.J:私の答えではありませんが、「ケース」は「if-then-else」を一般化します(2ケースから多数)
JosephDoggie

12

あるテーブルから別のテーブルに結果を転送するのではなく、初めてテーブルに結果を挿入する場合、これはOracle 11.2gで機能します。

INSERT INTO customers (last_name, first_name, city)
    SELECT 'Doe', 'John', 'Chicago' FROM dual
    WHERE NOT EXISTS 
        (SELECT '1' from customers 
            where last_name = 'Doe' 
            and first_name = 'John'
            and city = 'Chicago');

4
タグはSQL Server、TSQLを示しています
Malachi

11

CASEステートメントの代替ソリューションとして、テーブル駆動アプローチを使用できます。

DECLARE @Product TABLE (ID INT, Obsolete VARCHAR(10), InStock VARCHAR(10))
INSERT INTO @Product VALUES
(1,'N','Y'),
(2,'A','B'),
(3,'N','B'),
(4,'A','Y')

SELECT P.* , ISNULL(Stmt.Saleable,0) Saleable
FROM
    @Product P
    LEFT JOIN
        ( VALUES
            ( 'N', 'Y', 1 )
        ) Stmt (Obsolete, InStock, Saleable)
        ON  P.InStock = Stmt.InStock OR P.Obsolete = Stmt.Obsolete

結果:

ID          Obsolete   InStock    Saleable
----------- ---------- ---------- -----------
1           N          Y          1
2           A          B          0
3           N          B          1
4           A          Y          1

Salableはクエリのwhere条件で使用されていますか?
Bhavin Thummar

どこでも使えるコンディション。
Serkan Arslan、

9
SELECT CASE WHEN Obsolete = 'N' or InStock = 'Y' THEN 1 ELSE 0 
             END AS Saleable, * 
FROM Product


6
  SELECT IIF(Obsolete = 'N' OR InStock = 'Y',1,0) AS Saleable, * FROM Product

7
こんにちはSurjeet Singh Bisht; あなたのコードは正しいかもしれませんが、いくつかのコンテキストでそれはより良い答えになります。たとえば、関連するドキュメントへのリンクを含めて、この提案された変更が質問者の問題を解決する方法と理由を説明できます。それは彼らにとってより有用であり、同様の問題の解決策を探している他のサイト読者にとってもより有用です。
Vince Bowdren 2016年

5
この答えは何も新しいものを追加しません。実際、これとまったく同じ行が5年以上の間、受け入れられた回答の一部でした。
SLバース-2016年

1
さらに、IIFは2012年以降のSQL Serverにのみ適用されることも重要です
Ivan Rascon 2017年

5

これを実際に実装するには、2つの選択肢があります。

  1. SQL Server 2012から導入されたIIFの使用:

    SELECT IIF ( (Obsolete = 'N' OR InStock = 'Y'), 1, 0) AS Saleable, * FROM Product
  2. 使用Select Case

    SELECT CASE
        WHEN Obsolete = 'N' or InStock = 'Y'
            THEN 1
            ELSE 0
        END as Saleable, *
        FROM Product

4

質問:

SELECT IF(Obsolete = 'N' OR InStock = 'Y' ? 1 : 0) AS Saleable, * FROM Product

ANSI:

Select 
  case when p.Obsolete = 'N' 
  or p.InStock = 'Y' then 1 else 0 end as Saleable, 
  p.* 
FROM 
  Product p;

エイリアスを使用pすると(この場合は)、問題の防止に役立ちます。


3

SQL CASEの使用は、通常のIf / Elseステートメントと同じです。以下のクエリでは、廃止された値= 'N'またはIf InStock値= 'Y'の場合、出力は1になります。それ以外の場合、出力は0になります。次に、その0または1の値をSalable列の下に配置します。

SELECT
      CASE 
        WHEN obsolete = 'N' OR InStock = 'Y' 
        THEN 1 
        ELSE 0 
      END AS Salable
      , * 
FROM PRODUCT

1
いいですね。それを説明するためにたぶん単語か2つ?
JQSOFT

通常のIf / Elseステートメントと同じです。廃止値=「N」または場合INSTOCK値場合=「Y」出力は1.それ以外の場合、出力は0になりあろう
Tharuka

1
ありがとうございました。この説明を追加するには、投稿を編集してください。Like:If..Then...Else..ステートメントの使用法はSQL次のとおりです...
JQSOFT

2
SELECT 
  CAST(
    CASE WHEN Obsolete = 'N' 
    or InStock = 'Y' THEN ELSE 0 END AS bit
  ) as Saleable, * 
FROM 
  Product

8
口コミから:スタックオーバーフローへようこそ!ソースコードだけで答えないでください。ソリューションがどのように機能するかについて、わかりやすい説明を提供してください。参照:良い答えを書くにはどうすればよいですか?。おかげで
sɐunıɔןɐqɐp

3
「THEN」キーワードに続く出力がないため、これは実行されないことがわかります。
ドデカフォン

詳しく説明できますか?
Peter Mortensen

2

それはそのようなものになります:

SELECT OrderID, Quantity,
CASE
    WHEN Quantity > 30 THEN "The quantity is greater than 30"
    WHEN Quantity = 30 THEN "The quantity is 30"
    ELSE "The quantity is under 30"
END AS QuantityText
FROM OrderDetails;

クエリのwhere条件でQuantityText値を使用できますか?例SELECT OrderID, Quantity, CASE WHEN Quantity > 30 THEN "The quantity is greater than 30" WHEN Quantity = 30 THEN "The quantity is 30" ELSE "The quantity is under 30" END AS QuantityText FROM OrderDetails WHERE QuantityText = 'The quantity is 30';
Bhavin Thummar

1

完全を期すために、SQLでは3値論理を使用することを付け加えておきます。表現:

obsolete = 'N' OR instock = 'Y'

次の3つの異なる結果が生成される可能性があります。

| obsolete | instock | saleable |
|----------|---------|----------|
| Y        | Y       | true     |
| Y        | N       | false    |
| Y        | null    | null     |
| N        | Y       | true     |
| N        | N       | true     |
| N        | null    | true     |
| null     | Y       | true     |
| null     | N       | null     |
| null     | null    | null     |

したがって、たとえば、製品が陳腐化していても、在庫があるかどうかわからない場合、製品が販売可能かどうかはわかりません。この3値ロジックは次のように記述できます。

SELECT CASE
           WHEN obsolete = 'N' OR instock = 'Y' THEN 'true'
           WHEN NOT (obsolete = 'N' OR instock = 'Y') THEN 'false'
           ELSE NULL
       END AS saleable

それがどのように機能するかを理解したら、nullの動作を決定することにより、3つの結果を2つの結果に変換できます。たとえば、これはnullを販売不可能として扱います。

SELECT CASE
           WHEN obsolete = 'N' OR instock = 'Y' THEN 'true'
           ELSE 'false' -- either false or null
       END AS saleable

0

CASEステートメントの使用は好きですが、SQL SelectでIFステートメントを質問しました。私が過去に使用したものは次のとおりです。

SELECT

   if(GENDER = "M","Male","Female") as Gender

FROM ...

これは、条件の後に真の条件が続き、次に偽の条件が続くExcelまたはシートのIFステートメントのようなものです。

if(condition, true, false)

さらに、ifステートメントをネストすることができます(ただし、CASEを使用する必要があります:-)

(注:これはMySQLWorkbenchで機能しますが、他のプラットフォームでは機能しない場合があります)


0

Caseステートメントを使用できます。

Select 
Case WHEN (Obsolete = 'N' or InStock = 'Y') THEN 1 ELSE 0 END Saleable,
Product.*
from Product
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.