如何在SQL SELECT中执行IF ... THEN?

Eri*_*sky 1438 sql t-sql sql-server if-statement case

我如何IF...THENSQL SELECT声明中执行?

例如:

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

Dar*_*ler 1692

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
Run Code Online (Sandbox Code Playgroud)

你只需要做CAST结果如果你想把结果作为一个布尔值,如果你对a感到满意int,这可行:

SELECT CASE
            WHEN Obsolete = 'N' or InStock = 'Y'
               THEN 1
               ELSE 0
       END as Saleable, *
FROM Product
Run Code Online (Sandbox Code Playgroud)

CASE语句可以嵌入到其他CASE语句中,甚至包含在聚合中.

SQL Server Denali(SQL Server 2012)添加了IIF语句,该语句也可用于访问 :( Martin Smith指出)

SELECT IIF(Obsolete = 'N' or InStock = 'Y', 1, 0) as Saleable, * FROM Product
Run Code Online (Sandbox Code Playgroud)

  • 使用案例时,请注意不要在条件中包含您的条件.花了很多时间才意识到:) (55认同)
  • 并且不要忘记END (17认同)
  • 和AS位! (8认同)
  • Case,When,Else和End应该缩进平行(沿同一条线) - 然后才应该向内缩进 - 对我来说效果最好. (8认同)
  • @ReeveStrife仅限iif SQL Server 2012+ (5认同)
  • 谨防CASE/IIF的肮脏秘密:https://sqlperformance.com/2014/06/t-sql-queries/dirty-secrets-of-the-case-expression (2认同)

Jon*_*han 320

在这种情况下,case语句是你的朋友,并采用以下两种形式之一:

简单的案例:

SELECT CASE <variable> WHEN <value>      THEN <returnvalue>
                       WHEN <othervalue> THEN <returnthis>
                                         ELSE <returndefaultcase>
       END AS <newcolumnname>
FROM <table>
Run Code Online (Sandbox Code Playgroud)

扩展案例:

SELECT CASE WHEN <test>      THEN <returnvalue>
            WHEN <othertest> THEN <returnthis>
                             ELSE <returndefaultcase>
       END AS <newcolumnname>
FROM <table>
Run Code Online (Sandbox Code Playgroud)

您甚至可以将case语句放在order by子句中,以实现真正的花哨排序.

  • 我知道这是旧的,但我认为应该注意你可以在`END`之后添加一个`AS Col_Name`来命名结果列 (32认同)
  • 我总觉得第二个更简单. (9认同)
  • 同意,我几乎总是使用扩展的case语句,因为我想要测试的条件总是比一个变量本身更复杂.这对我来说也更容易阅读. (4认同)
  • 对两种情况都有很好的解释,有或没有变量。对于变量,条件需要满足 case 语句之后的变量与您的条件所基于的变量之间的相等性,如果没有变量,您可以添加一个自给自足的条件进行测试。 (2认同)

Mar*_*ith 260

从SQL Server 2012,您可以使用此IIF功能.

SELECT IIF(Obsolete = 'N' OR InStock = 'Y', 1, 0) AS Salable, *
FROM   Product
Run Code Online (Sandbox Code Playgroud)

这实际上只是一种简写(尽管不是标准的SQL)写作方式CASE.

与扩展CASE版本相比,我更喜欢简洁.

双方IIF()CASE解决作为SQL语句中的表达式,只能在使用明确的地方.

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
Run Code Online (Sandbox Code Playgroud)

但是,有时必须注意避免使用这种方法的参数嗅探问题.

  • 如果你想在SQL中使用IF .. then语句,这应该是答案. (4认同)

sve*_*ven 89

您可以在SQL CASE语句的强大功能中找到一些不错的示例,我认为您可以使用的语句将是这样的(来自4guysfromrolla):

SELECT
    FirstName, LastName,
    Salary, DOB,
    CASE Gender
        WHEN 'M' THEN 'Male'
        WHEN 'F' THEN 'Female'
    END
FROM Employees
Run Code Online (Sandbox Code Playgroud)

  • 请参阅:http://meta.stackexchange.com/questions/103053/how-aggressively-should-we-maintain-and-improve-very-popular-questions进行有趣的讨论.我提供的两个链接确实添加了额外的上下文,我支持. (4认同)
  • 该引用确实有用,强烈建议在其他详细信息的情况下使用 (2认同)

pal*_*rse 75

使用CASE.像这样的东西.

SELECT Salable =
        CASE Obsolete
        WHEN 'N' THEN 1
        ELSE 0
    END
Run Code Online (Sandbox Code Playgroud)


Joh*_*han 49

SELECT  
(CASE 
     WHEN (Obsolete = 'N' OR InStock = 'Y') THEN 'YES'
                                            ELSE 'NO' 
 END) as Salable
, * 
FROM Product
Run Code Online (Sandbox Code Playgroud)


San*_*pas 45

 SELECT
   CASE 
      WHEN OBSOLETE = 'N' or InStock = 'Y' THEN 'TRUE' 
      ELSE 'FALSE' 
   END AS Salable,
   * 
FROM PRODUCT
Run Code Online (Sandbox Code Playgroud)


use*_*658 45

Microsoft SQL Server(T-SQL)

在选择使用中:

select case when Obsolete = 'N' or InStock = 'Y' then 'YES' else 'NO' end
Run Code Online (Sandbox Code Playgroud)

在where子句中,使用:

where 1 = case when Obsolete = 'N' or InStock = 'Y' then 1 else 0 end
Run Code Online (Sandbox Code Playgroud)


Ken*_*Ken 44

从这个环节中,我们可以uderstand IF THEN ELSEIF THEN ELSE:

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' 
Run Code Online (Sandbox Code Playgroud)

这对T-SQL来说不够好吗?

  • 这不是请求者想要的,但知道你可以在select语句之外使用if语句*非常有用. (3认同)
  • EXISTS很好,因为如果找到项目,它会从搜索循环中踢出.COUNT运行直到表行结束.与问题无关,但有些事要知道. (2认同)

Rav*_*and 30

SQL Server中简单的if-else语句:

DECLARE @val INT;
SET @val = 15;

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

GO
Run Code Online (Sandbox Code Playgroud)

在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
Run Code Online (Sandbox Code Playgroud)

  • 迟了,但是可以按OP要求在`SELECT`中使用吗? (2认同)

小智 24

使用CASE声明:

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

etc...
Run Code Online (Sandbox Code Playgroud)


Tom*_*ito 24

使用纯位逻辑:

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
Run Code Online (Sandbox Code Playgroud)

请参阅工作演示:如果没有MSSQL中的情况

首先,您需要计算所选条件的值casetrue.这里有两个NULLIF:

for true: ISNULL(NULLIF(p.[Instock], 'Y'), 1)
for false: ISNULL(NULLIF(p.[Instock], 'N'), 0)
Run Code Online (Sandbox Code Playgroud)

组合在一起得到1或0.接下来使用按位运算符.

这是最WYSIWYG方法.

  • -1代码混淆.说真的,这与你所能得到的WYSIWYG差不多!一个红润不可思议的混乱,如果我不得不处理你的代码,我会整天诅咒......对不起: - / (17认同)
  • @Heliac将cte部分放入View中,你永远不会看到混乱.对于漫长而复杂的AND,OR,不是它比CASE(当然在cte之外的部分)更具可读性. (2认同)
  • 完全同意@Heliac。虽然它在语法上是正确的并且可以正常工作,但它并不容易得到支持。将其放在CTE中只会将这段不可读的代码移到其他地方。 (2认同)

san*_*wat 24

SQL Server 2012中添加了一个新功能IIF(我们可以简单地使用):

SELECT IIF ( (Obsolete = 'N' OR InStock = 'Y'), 1, 0) AS Saleable, * FROM Product
Run Code Online (Sandbox Code Playgroud)

  • 这个答案重复了(不太详细)几年前[马丁·史密斯的答案中已经提供的内容](/sf/answers/473886381/)。 (2认同)
  • 不是从我所看到的。它说您的答案发布于16年4月26日,马丁的发布于11年7月20日。 (2认同)

one*_*hen 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' )
Run Code Online (Sandbox Code Playgroud)


ati*_*ker 17

SELECT CASE WHEN profile.nrefillno = 0 THEN 'N' ELSE 'R'END as newref
From profile
Run Code Online (Sandbox Code Playgroud)


Cha*_*kya 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
Run Code Online (Sandbox Code Playgroud)

  • 你能否就这问题如何回答问题做一些解释? (2认同)

Jus*_*ohn 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]
Run Code Online (Sandbox Code Playgroud)


小智 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');
Run Code Online (Sandbox Code Playgroud)

  • 标签说SQL Server,TSQL (4认同)

Ser*_*lan 10

作为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
Run Code Online (Sandbox Code Playgroud)

结果:

ID          Obsolete   InStock    Saleable
----------- ---------- ---------- -----------
1           N          Y          1
2           A          B          0
3           N          B          1
4           A          Y          1
Run Code Online (Sandbox Code Playgroud)


小智 9

SELECT CASE WHEN Obsolete = 'N' or InStock = 'Y' THEN 1 ELSE 0 
             END AS Saleable, * 
FROM Product
Run Code Online (Sandbox Code Playgroud)


小智 8

使用 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
Run Code Online (Sandbox Code Playgroud)

  • 谢谢。请[编辑](https://stackoverflow.com/posts/60278997/edit)您的帖子添加此说明。比如:`SQL`中`If..Then...Else..`语句的用法如下...... (2认同)

Dib*_*bin 6

对于那些使用SQL Server 2012的用户,IIF是一个已添加的功能,可作为Case语句的替代方案.

SELECT IIF(Obsolete = 'N' OR InStock = 'Y', 1, 0) AS Salable, *
FROM   Product 
Run Code Online (Sandbox Code Playgroud)

  • 这个答案重复了(不太详细)几年前[马丁·史密斯的答案中已经提供的内容](/sf/answers/473886381/)。 (2认同)

小智 6

  SELECT IIF(Obsolete = 'N' OR InStock = 'Y',1,0) AS Saleable, * FROM Product
Run Code Online (Sandbox Code Playgroud)

  • 嗨Surjeet Singh Bisht; 你的代码可能是正确的,但有了一些上下文,它会得到更好的答案; 例如,您可以解释此提议的更改将如何以及为何解决提问者的问题,可能包括相关文档的链接.这将使它对他们更有用,对于寻找类似问题解决方案的其他网站读者也更有用. (6认同)
  • 这个答案没有添加任何新内容.事实上,这个完全相同的行已经成为已接受答案的一部分[超过5年](http://stackoverflow.com/posts/63480/revisions). (5认同)

小智 5

问题:

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

美国国家标准协会:

Select 
  case when p.Obsolete = 'N' 
  or p.InStock = 'Y' then 1 else 0 end as Saleable, 
  p.* 
FROM 
  Product p;
Run Code Online (Sandbox Code Playgroud)

在这种情况下,使用别名p将有助于防止出现问题。


小智 5

您可以有两种选择来实际实施:

  1. 使用从 SQL Server 2012 引入的 IIF:

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

    SELECT CASE
        WHEN Obsolete = 'N' or InStock = 'Y'
            THEN 1
            ELSE 0
        END as Saleable, *
        FROM Product
    
    Run Code Online (Sandbox Code Playgroud)


yus*_*ver 5

SELECT
if((obsolete = 'N' OR instock = 'Y'), 1, 0) AS saleable, *
FROM
product;
Run Code Online (Sandbox Code Playgroud)