How do I perform an IF…THEN in an SQL SELECT?
我如何执行在IF...THEN在SQL 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。 首先,您需要计算所选条件下的true和false的值。以下是两个零位:
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 |
|