如何IF...THEN
在SQL SELECT
陈述中执行?
例如:
SELECT IF(Obsolete = 'N' OR InStock = 'Y' ? 1 : 0) AS Saleable, * FROM Product
WHERE
,CHECK
但不适用于SELECT
。
如何IF...THEN
在SQL SELECT
陈述中执行?
例如:
SELECT IF(Obsolete = 'N' OR InStock = 'Y' ? 1 : 0) AS Saleable, * FROM Product
WHERE
,CHECK
但不适用于SELECT
。
Answers:
该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
在这种情况下,案例陈述是您的朋友,采用两种形式之一:
简单的情况:
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语句放在order by子句中,以进行真正的排序。
AS Col_Name
后面加上a END
来命名结果列
在SQL Server 2012中,您可以使用此IIF
功能。
SELECT IIF(Obsolete = 'N' OR InStock = 'Y', 1, 0) AS Salable, *
FROM Product
实际上,这只是一种简写(尽管不是标准的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
您可以在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
通过此链接,我们可以IF THEN ELSE
在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'
对于T-SQL来说这还不够吗?
SELECT
CASE
WHEN OBSOLETE = 'N' or InStock = 'Y' THEN 'TRUE'
ELSE 'FALSE'
END AS Salable,
*
FROM PRODUCT
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
SELECT
按照OP的要求在内部使用吗?
SQL Server 2012中添加了一个新功能IIF(我们可以简单地使用它):
SELECT IIF ( (Obsolete = 'N' OR InStock = 'Y'), 1, 0) AS Saleable, * FROM Product
使用纯位逻辑:
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
请参阅工作演示:如果没有case
,则在SQL Server中。
首先,您需要计算true
和false
选定条件的值。这是两个NULLIF:
for true: ISNULL(NULLIF(p.[Instock], 'Y'), 1)
for false: ISNULL(NULLIF(p.[Instock], 'N'), 0)
组合在一起得出1或0。接下来使用按位运算符。
这是最所见即所得的方法。
SELECT CASE WHEN profile.nrefillno = 0 THEN 'N' ELSE 'R'END as newref
From profile
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语句的示例。它具有嵌套的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]
CASE
被投票并标记为答案,而不是IF
应该作为答案的答案,就像这样,这仍然是一个CASE
陈述,而不是一个IF
。
如果您是第一次将结果插入表中,而不是将结果从一个表转移到另一个表,那么这在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');
作为该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
SELECT CASE WHEN Obsolete = 'N' or InStock = 'Y' THEN 1 ELSE 0
END AS Saleable, *
FROM Product
对于使用SQL Server 2012的用户,IIF是一项已添加的功能,可替代Case语句。
SELECT IIF(Obsolete = 'N' OR InStock = 'Y', 1, 0) AS Salable, *
FROM Product
SELECT IIF(Obsolete = 'N' OR InStock = 'Y',1,0) AS Saleable, * FROM Product
SELECT
CAST(
CASE WHEN Obsolete = 'N'
or InStock = 'Y' THEN ELSE 0 END AS bit
) as Saleable, *
FROM
Product
将会是这样的:
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;
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';
为了完整起见,我要补充一点,SQL使用三值逻辑。表达方式:
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 |
因此,例如,如果某产品已过时,但您不知道该产品是否有库存,则您不知道该产品是否可销售。您可以按如下所示编写此三值逻辑:
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的行为将三个结果转换为两个结果。例如,这会将null视为不可销售:
SELECT CASE
WHEN obsolete = 'N' OR instock = 'Y' THEN 'true'
ELSE 'false' -- either false or null
END AS saleable
我喜欢使用CASE语句,但是这个问题要求在SQL Select中使用IF语句。我过去使用的是:
SELECT
if(GENDER = "M","Male","Female") as Gender
FROM ...
就像excel或工作表IF语句一样,先有条件,然后是真条件,然后是假条件:
if(condition, true, false)
此外,您可以嵌套if语句(但随后使用应使用CASE :-)
(注意:这在MySQLWorkbench中有效,但在其他平台上可能无效)