关于sql server:如何在SQL SELECT中执行IF … THEN?

关于sql server:如何在SQL SELECT中执行IF … THEN?

How do I perform an IF…THEN in an SQL SELECT?

我如何执行在IF...THENSQL SELECT语句?

例如:

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

CASE语句是SQL中最接近if的语句,所有版本的SQL Server都支持该语句。

1
2
3
4
5
6
7
SELECT CAST(
             CASE
                  WHEN Obsolete = 'N' OR InStock = 'Y'
                     THEN 1
                  ELSE 0
             END AS bit) AS Saleable, *
FROM Product

如果希望结果为布尔值,则只需执行CAST。如果你对int满意,这就可以:

1
2
3
4
5
6
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语句,该语句在Access中也可用(由Martin Smith指出):

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


案例陈述是您在这种情况下的朋友,采用两种形式之一:

简单的例子:

1
2
3
4
5
SELECT CASE <variable> WHEN <value>      THEN <returnvalue>
                       WHEN <othervalue> THEN <returnthis>
                                         ELSE <returndefaultcase>
       END AS <newcolumnname>
FROM <table>

扩展案例:

1
2
3
4
5
SELECT CASE WHEN <test>      THEN <returnvalue>
            WHEN <othertest> THEN <returnthis>
                             ELSE <returndefaultcase>
       END AS <newcolumnname>
FROM <table>

您甚至可以将case语句放在order by子句中,以便进行真正奇特的排序。


在SQL Server 2012中,您可以使用IIF函数来实现这一点。

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

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

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

IIF()CASE都在SQL语句中解析为表达式,只能在定义良好的地方使用。

The CASE expression cannot be used to control the flow of execution of
Transact-SQL statements, statement blocks, user-defined functions, and
stored procedures.

如果这些限制不能满足您的需求(例如,需要根据某些条件返回不同形状的结果集),那么SQL Server也有一个过程性的IF关键字。

1
2
3
4
5
6
7
8
9
10
IF @IncludeExtendedInformation = 1
  BEGIN
      SELECT A,B,C,X,Y,Z
      FROM   T
  END
ELSE
  BEGIN
      SELECT A,B,C
      FROM   T
  END

但是,有时必须小心避免使用这种方法时出现参数嗅探问题。


您可以在SQL case语句的强大功能中找到一些很好的示例,我认为您可以使用的语句如下(来自4Guysfromrolla):

1
2
3
4
5
6
7
8
SELECT
    FirstName, LastName,
    Salary, DOB,
    CASE Gender
        WHEN 'M' THEN 'Male'
        WHEN 'F' THEN 'Female'
    END
FROM Employees


用例。像这样。

1
2
3
4
5
SELECT Salable =
        CASE Obsolete
        WHEN 'N' THEN 1
        ELSE 0
    END


1
2
3
4
5
6
7
SELECT  
(CASE
     WHEN (Obsolete = 'N' OR InStock = 'Y') THEN 'YES'
                                            ELSE 'NO'
 END) AS Salable
, *
FROM Product

1
2
3
4
5
6
7
 SELECT
   CASE
      WHEN OBSOLETE = 'N' OR InStock = 'Y' THEN 'TRUE'
      ELSE 'FALSE'
   END AS Salable,
   *
FROM PRODUCT

Microsoft SQL Server(T-SQL)

select中,使用:

1
SELECT CASE WHEN Obsolete = 'N' OR InStock = 'Y' THEN 'YES' ELSE 'NO' END

where条款中,使用:

1
WHERE 1 = CASE WHEN Obsolete = 'N' OR InStock = 'Y' THEN 1 ELSE 0 END


通过这个链接,我们可以理解T-SQL中的IF THEN ELSE

1
2
3
4
5
6
7
8
9
10
11
12
13
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来说还不够好吗?


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

1
2
3
4
5
6
7
8
9
DECLARE @val INT;
SET @val = 15;

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

GO

SQL Server中嵌套的if…else语句-

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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


使用纯位逻辑:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
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

请参见工作演示:如果没有,则SQL Server中的CASE

首先,您需要计算所选条件下的truefalse的值。以下是两个零位:

1
2
FOR TRUE: ISNULL(NULLIF(p.[Instock], 'Y'), 1)
FOR FALSE: ISNULL(NULLIF(p.[Instock], 'N'), 0)

加在一起得到1或0。接下来使用位运算符。

这是最WYSIWYG的方法。


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

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

使用案例陈述:

1
2
3
4
5
6
7
SELECT CASE
       WHEN (Obsolete = 'N' OR InStock = 'Y')
       THEN 'Y'
       ELSE 'N'
END AS Available

etc...

1
2
3
4
5
6
7
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' )


1
2
SELECT CASE WHEN profile.nrefillno = 0 THEN 'N' ELSE 'R'END AS newref
FROM profile


1
2
3
4
5
6
7
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

这不是答案,只是在我工作的地方使用的一个案例陈述的例子。它有一个嵌套的case语句。现在你知道为什么我的眼睛是交叉的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
 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]


如果您是第一次将结果插入到表中,而不是将结果从一个表传输到另一个表中,这在Oracle 11.2g中有效:

1
2
3
4
5
6
7
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');


作为CASE语句的替代解决方案,可以使用表驱动方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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

结果:

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


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

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

对于那些使用SQL Server 2012的用户,IIF是一个已经添加的功能,可以作为case语句的替代。

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


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

  • 使用从SQL Server 2012引入的IIF:

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

    1
    2
    3
    4
    5
    6
    SELECT CASE
        WHEN Obsolete = 'N' OR InStock = 'Y'
            THEN 1
            ELSE 0
        END AS Saleable, *
        FROM Product


  • 问题:

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

    美国国家标准协会:

    1
    2
    3
    4
    5
    6
    SELECT
      CASE WHEN p.Obsolete = 'N'
      OR p.InStock = 'Y' THEN 1 ELSE 0 END AS Saleable,
      p.*
    FROM
      Product p;

    使用别名(在本例中为p)将有助于防止出现问题。


    1
    2
    3
    4
    5
    6
    7
    SELECT
      CAST(
        CASE WHEN Obsolete = 'N'
        OR InStock = 'Y' THEN ELSE 0 END AS bit
      ) AS Saleable, *
    FROM
      Product

    推荐阅读

      linux定时执行命令?

      linux定时执行命令?,时间,系统,服务,任务,工作,标准,情况,周期性,工具,命令,l

      linux看命令执行过程?

      linux看命令执行过程?,系统,服务,状态,软件,时间,数据,地址,命令,进程,情况,l

      linux登陆执行命令?

      linux登陆执行命令?,系统,服务,工具,地址,密码,百度,管理,检测,网络,第一,怎

      linux远程执行多命令?

      linux远程执行多命令?,工具,服务,命令,状态,暂停,代码,底部,时间,地址,系统,L

      linux下执行命令行?

      linux下执行命令行?,工作,系统,信息,单位,命令,基础,地址,设备,权威,标准,mv

      linux安装执行命令?

      linux安装执行命令?,系统,软件,网络,密码,官方网站,在线,工作,盘中,电脑,第

      linux执行命令超时?

      linux执行命令超时?,时间,代码,系统,名字,环境,工作,服务,下来,名称,地址,如

      linux远程执行多命令?

      linux远程执行多命令?,工具,服务,命令,状态,暂停,代码,底部,时间,地址,系统,L

      linux命令行执行工具?

      linux命令行执行工具?,工具,系统,网络,分析,工作,服务,状态,信息,电脑,发行,s

      linux执行命令超时?

      linux执行命令超时?,时间,代码,系统,名字,环境,工作,服务,下来,名称,地址,如

      linux安装执行命令?

      linux安装执行命令?,系统,软件,网络,密码,官方网站,在线,工作,盘中,电脑,第

      linux执行两条命令?

      linux执行两条命令?,单位,工作,地址,命令,连续,系统,分行,权威,信息,目录,Lin

      linux执行pl命令?

      linux执行pl命令?,代码,服务,工具,位置,标准,系统,首页,数据,操纵,环境,perl

      linux命令执行10次?

      linux命令执行10次?,地址,工作,信息,系统,命令,目录,标准,设备,发行,文件,Lin

      linux执行命令后无号?

      linux执行命令后无号?,系统,环境,信息,工具,状态,数据,命令,文件,字符集,环

      linux周期执行命令?

      linux周期执行命令?,工作,系统,周期,地址,命令,工具,信息,时间,任务,目录,lin

      linux执行命令被阻止?

      linux执行命令被阻止?,档案,系统,服务,网络,工具,在线,信息,基础,状态,命令,

      写5条linux命令语句?

      写5条linux命令语句?,工作,地址,系统,信息,目录,命令,管理,标准,功能,文件,li

      linux执行命令大全?

      linux执行命令大全?,工作,系统,地址,信息,命令,目录,工具,基础,设备,发行,Lin

      循环执行linux命令?

      循环执行linux命令?,工具,系统,名称,代码,第一,环境,位置,数字,脚本,变量,Lin