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 :이 기사는 논리적 재 작성 규칙을 사용하여 의미를 분리로 변환하는 방법에 대해 설명하므로 실제로는 관련이 없습니다. 단서는 '논리적'이라는 단어입니다. 즉, 투영에 적용되지 않는 참 또는 거짓으로 해석되는 것입니다. TL; DR 문서가 적용 WHERE하고 CHECK있지만 SELECT.
16:06에

6
@MartinSmith의 대답은 가장 우아합니다-SQL 2012+에서 IIF를 사용하십시오.
Murray Foxcroft

답변:


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
그리고 끝을 잊지 마세요
Simon_Weaver

8
그리고 AS 비트!
Cas Bloem

8
Case, When, Else 및 End는 (동일한 줄을 따라) 평행하게 들여 쓰기해야하며 더 안쪽으로 들여 쓰기해야합니다.
Ujjwal Singh

6
@ReeveStrife iif SQL Server 2012+에만 해당
stuartdotnet

327

이 상황에 대한 사례 진술은 귀하의 친구이며 다음 두 가지 형식 중 하나를 취합니다.

간단한 경우 :

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 by 절에 case 문을 넣을 수도 있습니다.


32
나는 이것이 오래 알고,하지만 난 당신이를 추가 할 수 있음에 유의해야한다고 생각 AS Col_Name애프터 END결과 열 이름을

9
나는 항상 두 번째 것이 더 간단한 것처럼 느낍니다.
Hogan

4
동의합니다. 테스트하려는 조건이 하나의 변수 자체보다 항상 더 복잡하기 때문에 거의 항상 확장 사례 문을 사용합니다. 또한 읽기가 더 쉬워졌습니다.
magnum_pi

1
변수의 유무에 관계없이 두 상황에 대한 좋은 설명. 변수를 사용하면 조건은 case 문 다음에 나오는 변수와 조건을 기반으로 한 변수 사이의 동등성을 충족시켜야합니다. 변수없이 테스트하기에 자급 자족 조건을 추가 할 수 있습니다.
Remus. A

두 번째 옵션으로 더 편리합니다. 둘은 똑같이 괜찮습니다.
Stanley Okpala Nwosa

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 .. 문을 원한다면 이것이 답이 될 것입니다.
Mr.J

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/… 을 참조하십시오 . 귀하가 제공하는 두 개의 링크는 추가 컨텍스트를 추가하여 지원합니다.
Sam Saffron

2
참조는 추가 정보가 필요한 경우에 매우 유용하고 권장됩니다
baymax

75

CASE를 사용하십시오. 이 같은.

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

50
SELECT  
(CASE 
     WHEN (Obsolete = 'N' OR InStock = 'Y') THEN 'YES'
                                            ELSE 'NO' 
 END) as Salable
, * 
FROM Product

48

Microsoft SQL Server (T-SQL)

에서 다음 select을 사용하십시오.

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

A의 where절, 사용 :

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

1
where Obsolete = 'N' or InStock = 'Y'실제로 반을 반으로
자르지 않겠습니까

46

에서 이 링크 , 우리가 이해할 수있는 IF THEN ELSET-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 문을 사용할 수 있다는 것을 아는 것이 매우 유용 합니다.
Jonathan

2
항목이 있으면 검색 루프에서 쫓겨나 기 때문에 존재합니다. COUNT는 테이블 행이 끝날 때까지 실행됩니다. 질문과는 관련이 없지만 알아야 할 사항이 있습니다.
JustJohn


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
늦었지만 SELECTOP가 요청 한대로 내부 에서 사용할 수 있습니까?
abdul qayyum

25

SQL Server 2012 에는 새로운 기능인 IIF (간단히 사용할 수 있음)가 추가되었습니다.

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

1
이 답변은 몇 년 전에 Martin Smith가 답변에서 이미 제공 한 내용을 (더 자세하게) 반복 합니다.
jk7

1
@ jk7이 질문에 대한 첫 번째 답변이었습니다.
sandeep rawat

3
내가 본 것에서 아닙니다. 귀하의 답변이 April 26 '16에 게시되었고 Martin 's가 Jul 20 '11에 게시되었다고합니다.
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에 없는 경우 참조하십시오 .

처음에는, 당신은의 값 밖으로 작업을해야 true하고 false선정 조건. 다음은 두 개의 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 부분을 View에 넣고 엉망이되지 않습니다. 길고 복잡한 AND 또는 OR의 경우 CASE (물론 cte 외부)보다 읽기 쉽습니다.
Tomasito 2016 년

1
일단 cte에 들어 있으면 깔끔함을 위해 +1을 주었지만 현재 질문에 대한 대답이 잘못되었습니다. 당신은 '|'이 필요합니다 '&'가 아닙니다.
Mark Hurd

3
@Heliac에 전적으로 동의합니다. 문법적으로 정확하고 잘 작동하지만 쉽게 지원할 수는 없습니다. CTE에 넣으면 읽을 수없는 코드 조각이 다른 곳으로 이동합니다.
objectNotFound

1
조합을 확인하는 테이블 방법에는 장점이 있습니다. 테이블 변수를 사용하여 기존 쿼리에 조인하면 대 / 소문자없이 집합 기반 솔루션을 제공 할 수 있습니다. 이 답변은 좋지 않은 예이지만 테이블 아이디어 자체에는 장점이 있습니다.
Suncat2000

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 : 내 대답은 아니지만 '사례'는 '만약 그렇지 않은 경우'를 일반화합니다 (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을 사용하는 관점에서는 여전히 SQL이 모두 집중됩니다.
JustJohn

1
왜 그냥 방황하고있어 CASE대신의 답변으로 upvoted 및 표시되고 IF이 같은 대답을 했어야하는이 여전히입니다 CASEif 문, 없습니다 IF.
Mr.J

@ Mr.J : 내 대답은 아니지만 '사례'는 '만약 그렇지 않은 경우'를 일반화합니다 (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은 쿼리의 조건에 사용됩니까?
Bhavin Thummar

어디서든 사용할 수 있습니다.
Serkan Arslan

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

6

SQL Server 2012를 사용하는 사람들을 위해 IIF는 기능이 추가되어 Case 문의 대안으로 작동합니다.

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

1
이 답변은 몇 년 전에 Martin Smith가 답변에서 이미 제공 한 내용을 (더 자세하게) 반복 합니다.
jk7

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

7
안녕하세요 Surjeet Singh Bisht; 코드가 정확할 수도 있지만 일부 상황에서는 더 나은 답변을 얻을 수 있습니다. 예를 들어 제안 된 변경으로 인해 관련 문서에 대한 링크를 포함하여 질문자의 문제를 해결하는 방법과 이유를 설명 할 수 있습니다. 그것은 그들에게 더 유용 할 것이며, 비슷한 문제에 대한 해결책을 찾는 다른 사이트 독자들에게도 더 유용 할 것입니다.
빈스 Bowdren

5
이 답변은 새로운 것을 추가하지 않습니다. 사실이 같은 줄은 5 년 넘게 받아 들여진 답변의 일부였습니다 .
SL Barth-복원 Monica Monica

1
또한 IIF 는 2012 년부터 SQL Server에만 적용 된다는 점을 언급하는 것이 중요합니다.
Ivan Rascon

5

실제로 구현하기 위해 두 가지 선택을 할 수 있습니다.

  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'또는 InStock 값 = 'Y'인 경우 출력은 1이됩니다. 그렇지 않으면 출력이 0이됩니다. 그런 다음 해당 0 또는 1 값을 판매 가능 열 아래에 놓습니다.

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

1
좋은 데요 어쩌면 한두 단어로 설명해 주시겠습니까?
JQSOFT

일반적인 If / Else 문과 같습니다. 사용되지 않는 값 = 'N'또는 InStock 값 = 'Y'인 경우 출력은 1이됩니다. 그렇지 않으면 출력은 0이됩니다.
Tharuka

1
감사합니다. 제발 편집 이 설명을 추가 할 수 귀하의 게시물을. 좋아 : 다음과 같이 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
리뷰에서 : Stack Overflow에 오신 것을 환영합니다! 소스 코드만으로는 대답하지 마십시오. 솔루션 작동 방식에 대한 좋은 설명을 제공하십시오. 참조 : 좋은 답변을 작성하려면 어떻게합니까? . 감사합니다
sɐunıɔ ןɐ qɐp

3
나는 'THEN'키워드 다음에 출력이 없기 때문에 이것이 실행되지 않는다고 생각합니다.
Dodecaphone

정교하게 할 수 있습니까?
Peter Mortensen 2016 년

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'

세 가지 뚜렷한 결과를 얻을 수 있습니다.

| 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 또는 sheet IF 문과 같습니다.

if(condition, true, false)

또한 if 문을 중첩 할 수 있습니다 (그러나 CASE :-를 사용해야합니다)

(참고 : 이것은 MySQLWorkbench에서는 작동하지만 다른 플랫폼에서는 작동하지 않을 수 있습니다)


0

사례 진술을 사용할 수 있습니다.

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.