Làm cách nào để thực hiện một IF ... THEN trong một câu lệnh SQL?


1,141

Làm cách nào để thực hiện một IF ... THEN trong câu lệnh SQL SELECT?

Ví dụ:

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

Bạn có thể muốn xem xét này [link] (http://weblogs.sqlteam.com/jeffs/archive/2003/11/14/513. aspx). Về: SQL WHERE mệnh đề: Tránh CASE, sử dụng logic Boolean 14 feb. 122012-02-14 21:21:23

+2

@ Người thân: không thực sự có liên quan bởi vì bài viết nói về việc sử dụng các quy tắc viết lại logic để chuyển đổi một hàm ý thành một sự tách rời. Các đầu mối là từ 'hợp lý' tức là một cái gì đó mà giải quyết thành sự thật hoặc sai, mà không áp dụng cho chiếu. TL; DR bài viết áp dụng cho 'WHERE' và' CHECK' nhưng không áp dụng 'SELECT'. 11 may. 162016-05-11 16:06:37

+2

@ MartinSmith của câu trả lời là thanh lịch nhất - sử dụng IIF trong SQL 2012+. 27 mar. 172017-03-27 13:06:02

1,372

Các CASE tuyên bố là gần nhất với IF trong SQL và được hỗ trợ trên tất cả các phiên bản của SQL Server

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

Bạn chỉ cần phải làm như CAST nếu bạn muốn kết quả như một giá trị boolean, nếu bạn hài lòng với một số int, hoạt động này:

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

Các câu lệnh CASE có thể được nhúng trong các câu lệnh CASE khác và thậm chí được bao gồm trong tập hợp.

SQL Server Denali (SQL Server 2012) bổ sung báo cáo kết quả IIF mà cũng có sẵn trong access: (chỉ ra bởi Martin Smith)

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

Chỉ cần một lời cảnh báo bổ sung không kèm theo các điều kiện của bạn trong bộ đệm khi sử dụng vỏ máy. Mất khá nhiều thời gian để nhận ra điều đó :) 13 sep. 112011-09-13 15:41:37

+10

và đừng quên END 28 jan. 142014-01-28 10:52:37

+4

và bit AS! 22 apr. 142014-04-22 12:49:30

+5

Trường hợp, khi nào, Khác và Cuối sẽ được thụt lề song song (cùng một dòng) - và chỉ sau đó nên thụt vào sâu hơn nữa - làm việc tốt nhất cho tôi. 01 jul. 142014-07-01 21:24:29

  0

Tôi đã có nhu cầu cho các CASE lồng nhau và đã quên rằng tôi cần nhiều kết hợp phù hợp. 10 jul. 152015-07-10 20:33:26

  0

Mặc dù hoạt động này, sử dụng hàm IFF() sẽ là câu trả lời tốt hơn 09 oct. 152015-10-09 15:42:56

  0

@ReeveStrife Ý của bạn là 'IIF()' https://msdn.microsoft.com/en-us/library/hh213574.aspx?f=255&MSPPError= -2147217396 30 mar. 162016-03-30 15:03:22

+3

@ReeveStrife Chỉ iif SQL Server 2012+ 30 may. 162016-05-30 03:26:07

+1

@ArchanMishra Hi Archan, bạn có thể giải thích cho tôi lý do tại sao bạn không nên kèm theo các điều kiện của bạn? 16 jan. 172017-01-16 12:30:07

  0

Hãy coi chừng bí mật bẩn của CASE/IIF: https://sqlperformance.com/2014/06/t-sql-queries/dirty-secrets-of-the-case-expression 27 jan. 172017-01-27 12:21:58

  0

@ArchanMishra bạn có thể. Tôi nghĩ anh ấy có nghĩa là nó sẽ làm chậm mọi thứ, nhưng không. Bạn có thể sử dụng các dấu ngoặc kép nhiều lần như bạn muốn trong SQL Server, miễn là nó có ý nghĩa logic đối với SQL. 21 mar. 172017-03-21 03:22:40

  0

@ DarrelMiller bạn có thể trả về TRUE hoặc FALSE trong câu lệnh CASE và tránh CAST, không chắc chắn nếu nó hoạt động trên SQL Server, nhưng tôi nghĩ đó là SQL. Tôi chưa bao giờ thấy bất cứ điều gì như vậy 20 jan. 182018-01-20 13:44:39


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

65

Sử dụng CASE. Một cái gì đó như thế này.

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

35
SELECT 
    CASE 
     WHEN OBSOLETE = 'N' or InStock = 'Y' THEN 'TRUE' 
     ELSE 'FALSE' 
    END AS Salable, 
    * 
FROM PRODUCT 

66

Bạn có thể tìm thấy một số ví dụ ngơi thoải mái tại The Power of SQL CASE Statements, và tôi nghĩ báo cáo kết quả mà bạn có thể sử dụng sẽ là một cái gì đó như thế này (từ 4guysfromrolla):

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

xem: http://meta.stackexchange.com/questions/103053/how-aggressively-should-we-maintain-and-improve-very-popular-questions cho một cuộc thảo luận thú vị. Tôi hai liên kết bạn cung cấp làm thêm ngữ cảnh bổ sung, mà tôi hỗ trợ. 19 aug. 112011-08-19 02:47:35

  0

Tham chiếu thực sự hữu ích và được khuyến nghị cao trong trường hợp các chi tiết bổ sung 07 dec. 162016-12-07 14:56:44


34

Microsoft SQL server (T-SQL)

Trong một sử dụng chọn:

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

Trong một mệnh đề where, sử dụng:

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

16

Sử dụng một tuyên bố CASE:

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

etc... 

256

Những tuyên bố trường hợp là bạn của bạn trong này tình huống và có một trong hai dạng:

Trường hợp đơn giản:

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

Trường hợp mở rộng:

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

Bạn thậm chí có thể đặt báo cáo trường hợp trong một trật tự quy định tại khoản cho đặt hàng thực sự ưa thích.

+27

Tôi biết điều này là cũ, nhưng tôi nghĩ cần lưu ý rằng bạn có thể thêm 'AS Col_Name' sau' END' để đặt tên cho cột kết quả là 18 jun. 122012-06-18 10:22:11

+5

. cảm thấy như thứ hai là đơn giản hơn. 15 apr. 162016-04-15 20:32:58

+2

Đồng ý, tôi hầu như luôn luôn kết thúc bằng cách sử dụng câu lệnh mở rộng vì các điều kiện tôi muốn thử nghiệm luôn phức tạp hơn chỉ một biến. Tôi cũng cảm thấy dễ đọc hơn. 18 may. 162016-05-18 16:34:49

  0

Giải thích tốt về cả hai tình huống, có hoặc không có biến.Với biến điều kiện cần thỏa mãn sự bình đẳng giữa biến sau câu lệnh trường hợp và biến bạn căn cứ điều kiện của mình, không có biến bạn có thể thêm điều kiện tự đủ để kiểm tra. 23 feb. 182018-02-23 11:24:50


31

Từ link này, chúng ta có thể uderstand IF THEN ELSE trong 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' 

không Đây có phải là tốt đủ cho T-SQL?

+2

Đây không phải là những gì người yêu cầu muốn, nhưng rất hữu ích khi biết rằng bạn có thể sử dụng nếu câu lệnh * bên ngoài * một câu lệnh chọn. 10 apr. 132013-04-10 08:06:51

+1

EXISTS là tốt vì nó đá ra khỏi vòng lặp tìm kiếm nếu mục được tìm thấy. COUNT chạy cho đến cuối hàng của bảng. Không có gì để làm với câu hỏi, nhưng một cái gì đó để biết. 11 feb. 162016-02-11 21:12:24


200

Từ SQL Server 2012, bạn có thể sử dụng IIF function cho việc này.

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

Đây chỉ là cách viết tắt (mặc dù không phải chuẩn SQL) CASE.

Tôi thích sự tương đồng khi so sánh với phiên bản mở rộng CASE.

Cả hai IIF()CASE giải quyết dưới dạng biểu thức trong câu lệnh SQL và chỉ có thể được sử dụng ở những nơi được xác định rõ.

Khái niệm TRƯỜNG HỢP không thể được sử dụng để kiểm soát dòng chảy của thực hiện báo cáo Transact-SQL, khối tuyên bố, hàm do người dùng định nghĩa, và thủ tục lưu trữ.

Nếu nhu cầu của bạn không được thỏa mãn bởi những giới hạn này (ví dụ: cần phải trả về các bộ kết quả có hình dạng khác nhau tùy thuộc vào điều kiện) thì SQL Server cũng có từ khóa IF thủ tục.

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

Care must sometimes be taken to avoid parameter sniffing issues with this approach however.

  0

Điều này sẽ là câu trả lời nếu bạn muốn một IF .. sau đó tuyên bố trong SQL. 16 mar. 172017-03-16 03:27:52


-3
CASE  
    WHEN CAST([PartnerProg Start Date] AS DATE) < CAST('1-Nov-2010' AS DATE) 
     AND CAST([PartnerProg End Date] AS DATE) > CAST('31-Jan-2011' AS DATE) 
    THEN 'Preferred or Gold' 
ELSE 
    '' 
END 
    AS 'Partner Segment 2 Q111', 

sử dụng này nếu bạn muốn so sánh nhiều hơn một ngày


7

Nếu bạn đang chèn kết quả vào một bảng cho lần đầu tiên, chứ không phải là chuyển giao kết quả từ một bảng khác, điều này hoạt động trong 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'); 
+2

các thẻ nói SQL Server, TSQL 27 dec. 122012-12-27 15:46:27


17

Sử dụng bit logi tinh khiết c:

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 

Xem working demo: IF THEN WITHOUT CASE IN MSSQL

Đối đầu, bạn cần phải làm việc ra giá trị của truefalse cho điều kiện lựa chọn. Ở đây có hai NULLIF:

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

kết hợp với nhau sẽ cho 1 hoặc 0. Tiếp theo sử dụng bitwise operators.

Đó là phương pháp WYSIWYG nhất.

+8

-1 cho Code Obfuscation. Nghiêm túc, đây là khoảng cách xa WYSIWYG như bạn có thể nhận được! Một mess lộn xộn không thể đọc được, và nếu tôi đã phải làm việc trên mã của bạn, tôi sẽ bị nguyền rủa cả ngày ... xin lỗi: -/ 22 jun. 132013-06-22 08:47:00

+1

@Heliac đặt cte một phần trong Xem và bạn sẽ không bao giờ thấy mớ hỗn độn. Đối với AND và OR dài và phức tạp, KHÔNG phải nó dễ đọc hơn CASE (phần bên ngoài cte của khóa học). 23 jun. 132013-06-23 09:52:05

  0

Tôi đã đưa ra một +1 cho sự gọn gàng, một khi nó ở trong một cte, nhưng lưu ý rằng câu trả lời hiện tại là sai cho câu hỏi. Bạn cần một '|' không phải là một '&'. 16 nov. 162016-11-16 00:19:38

  0

Hoàn toàn đồng ý với @Heliac. Trong khi nó là cú pháp chính xác và hoạt động tốt nó chỉ là không dễ dàng hỗ trợ. Đặt nó trong một CTE sẽ chỉ di chuyển đoạn mã không đọc được ở một nơi khác. 24 nov. 172017-11-24 17:04:22


3

Đối với những người sử dụng SQL Server 2012, IIF là một tính năng đã được thêm và hoạt động thay thế cho các câu lệnh Case.

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

10
SELECT CASE WHEN profile.nrefillno = 0 THEN 'N' ELSE 'R'END as newref 
From profile 

8
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 
+1

Bạn có thể đưa ra một số giải thích về cách câu trả lời cho câu hỏi này không? 09 dec. 152015-12-09 13:32:05


23

Simple if-else trong SQL   Server:

DECLARE @val INT; 
SET @val = 15; 

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

GO 

Nested Nếu ...tuyên bố khác trong máy chủ sql -

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 

8

Đây không phải là câu trả lời, chỉ là ví dụ về tuyên bố CASE khi tôi làm việc. Nó có một câu lệnh CASE lồng nhau. Bây giờ bạn biết lý do tại sao đôi mắt của tôi được vượt qua.

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] 
  0

Bản chỉnh sửa định dạng lại các câu lệnh Case là tất cả tốt đẹp và dandy và làm cho nó dễ hiểu hơn nhưng SQL sẽ vẫn tất cả gộp lại trong khung nhìn đang sử dụng nó. 12 oct. 162016-10-12 16:30:01

  0

Tôi chỉ lơ là lý do tại sao 'CASE' trở thành upvoted và được đánh dấu là câu trả lời thay vì' IF' mà phải là câu trả lời, như thế này, đây vẫn là 'CASE'statement, không phải là' IF'. 22 mar. 172017-03-22 07:16:38


16

Một tính năng mới, IIF (mà chúng ta chỉ có thể sử dụng), đã được bổ sung trong SQL Server 2012:

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

12
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') 

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

Hi Surjeet Singh Bisht; mã của bạn có thể đúng, nhưng với một số ngữ cảnh, nó sẽ tạo ra một câu trả lời tốt hơn; ví dụ: bạn có thể giải thích cách thức và lý do thay đổi được đề xuất này sẽ giải quyết vấn đề của người hỏi, có thể bao gồm liên kết đến tài liệu có liên quan. Điều đó sẽ làm cho nó hữu ích hơn cho họ, và cũng hữu ích hơn cho người đọc trang web khác, những người đang tìm kiếm các giải pháp cho các vấn đề tương tự. 30 nov. 162016-11-30 16:27:31

+1

Câu trả lời này không thêm bất kỳ điều gì mới. Trên thực tế, cùng một dòng này đã là một phần của câu trả lời được chấp nhận [trong hơn 5 năm] (http://stackoverflow.com/posts/63480/revisions). 30 nov. 162016-11-30 19:20:48

  0

Ngoài ra, điều quan trọng cần đề cập là [IIF] (https://msdn.microsoft.com/en-us/library/hh213574.aspx) chỉ áp dụng cho SQL Server bắt đầu từ năm 2012 26 jan. 172017-01-26 16:24:03


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

1

Là một giải pháp thay thế cho CASE có thể sử dụng phương pháp tiếp cận theo bảng hướng dẫn.

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 

Kết quả:

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