Como executo IF...THEN
uma SQL SELECT
declaração?
Por exemplo:
SELECT IF(Obsolete = 'N' OR InStock = 'Y' ? 1 : 0) AS Saleable, * FROM Product
WHERE
e CHECK
, mas não SELECT
.
Como executo IF...THEN
uma SQL SELECT
declaração?
Por exemplo:
SELECT IF(Obsolete = 'N' OR InStock = 'Y' ? 1 : 0) AS Saleable, * FROM Product
WHERE
e CHECK
, mas não SELECT
.
Respostas:
A CASE
instrução é a mais próxima de IF no SQL e é suportada em todas as versões do SQL Server.
SELECT CAST(
CASE
WHEN Obsolete = 'N' or InStock = 'Y'
THEN 1
ELSE 0
END AS bit) as Saleable, *
FROM Product
Você só precisa fazer isso CAST
se desejar o resultado como um valor booleano. Se você está satisfeito com um int
, isso funciona:
SELECT CASE
WHEN Obsolete = 'N' or InStock = 'Y'
THEN 1
ELSE 0
END as Saleable, *
FROM Product
CASE
instruções podem ser incorporadas em outras CASE
instruções e até incluídas em agregados.
O SQL Server Denali (SQL Server 2012) adiciona a instrução IIF , que também está disponível no acesso (apontada por Martin Smith ):
SELECT IIF(Obsolete = 'N' or InStock = 'Y', 1, 0) as Saleable, * FROM Product
A declaração de caso é sua amiga nessa situação e assume uma das duas formas:
O caso simples:
SELECT CASE <variable> WHEN <value> THEN <returnvalue>
WHEN <othervalue> THEN <returnthis>
ELSE <returndefaultcase>
END AS <newcolumnname>
FROM <table>
O caso estendido:
SELECT CASE WHEN <test> THEN <returnvalue>
WHEN <othertest> THEN <returnthis>
ELSE <returndefaultcase>
END AS <newcolumnname>
FROM <table>
Você pode até colocar instruções de caso em uma ordem por cláusula para pedidos realmente sofisticados.
AS Col_Name
após a END
nomear a coluna resultante
No SQL Server 2012, você pode usar a IIF
função para isso.
SELECT IIF(Obsolete = 'N' OR InStock = 'Y', 1, 0) AS Salable, *
FROM Product
Esta é efetivamente apenas uma maneira abreviada (embora não padrão do SQL) de escrever CASE
.
Eu prefiro a concisão quando comparado com a CASE
versão expandida .
Ambos IIF()
e CASE
resolvem como expressões em uma instrução SQL e só podem ser usados em locais bem definidos.
A expressão CASE não pode ser usada para controlar o fluxo de execução de instruções Transact-SQL, blocos de instruções, funções definidas pelo usuário e procedimentos armazenados.
Se suas necessidades não puderem ser atendidas por essas limitações (por exemplo, uma necessidade de retornar conjuntos de resultados de formas diferentes, dependendo de alguma condição), o SQL Server também terá uma IF
palavra-chave de procedimento .
IF @IncludeExtendedInformation = 1
BEGIN
SELECT A,B,C,X,Y,Z
FROM T
END
ELSE
BEGIN
SELECT A,B,C
FROM T
END
Às vezes, deve-se tomar cuidado para evitar problemas de detecção de parâmetros com essa abordagem .
Você pode encontrar alguns bons exemplos em Instruções do Power of SQL CASE , e acho que a instrução que você pode usar será algo assim (de 4guysfromrolla ):
SELECT
FirstName, LastName,
Salary, DOB,
CASE Gender
WHEN 'M' THEN 'Male'
WHEN 'F' THEN 'Female'
END
FROM Employees
Use CASE. Algo assim.
SELECT Salable =
CASE Obsolete
WHEN 'N' THEN 1
ELSE 0
END
SELECT
(CASE
WHEN (Obsolete = 'N' OR InStock = 'Y') THEN 'YES'
ELSE 'NO'
END) as Salable
, *
FROM Product
Microsoft SQL Server (T-SQL)
Em a select
, use:
select case when Obsolete = 'N' or InStock = 'Y' then 'YES' else 'NO' end
Em uma where
cláusula, use:
where 1 = case when Obsolete = 'N' or InStock = 'Y' then 1 else 0 end
where Obsolete = 'N' or InStock = 'Y'
e cortar o onde ao meio praticamente
Desde esta ligação , podemos compreender IF THEN ELSE
em 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'
Isso não é bom o suficiente para o T-SQL?
SELECT
CASE
WHEN OBSOLETE = 'N' or InStock = 'Y' THEN 'TRUE'
ELSE 'FALSE'
END AS Salable,
*
FROM PRODUCT
Instrução if-else simples no SQL Server:
DECLARE @val INT;
SET @val = 15;
IF @val < 25
PRINT 'Hi Ravi Anand';
ELSE
PRINT 'By Ravi Anand.';
GO
Instrução If ... else aninhada no SQL Server -
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
como OP pediu?
Um novo recurso, IIF (que podemos simplesmente usar), foi adicionado no SQL Server 2012:
SELECT IIF ( (Obsolete = 'N' OR InStock = 'Y'), 1, 0) AS Saleable, * FROM Product
Use lógica de bits pura:
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
Veja a demonstração de trabalho: se não houver case
no SQL Server .
Para começar, você precisa calcular o valor true
e false
para as condições selecionadas. Aí vem dois NULLIF :
for true: ISNULL(NULLIF(p.[Instock], 'Y'), 1)
for false: ISNULL(NULLIF(p.[Instock], 'N'), 0)
combinados fornece 1 ou 0. Em seguida, use operadores bit a bit .
É o método mais WYSIWYG .
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' )
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
Esta não é uma resposta, apenas um exemplo de uma declaração CASE em uso onde eu trabalho. Ele possui uma instrução CASE aninhada. Agora você sabe por que meus olhos estão cruzados.
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
ser votado e marcado como uma resposta em vez da IF
que deveria ter sido a resposta, como esta, essa ainda é uma CASE
afirmação, não uma IF
.
Se você estiver inserindo resultados em uma tabela pela primeira vez, em vez de transferir resultados de uma tabela para outra, isso funcionará no 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');
Como uma solução alternativa à CASE
instrução, uma abordagem orientada a tabela pode ser usada:
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
Resultado:
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
Para quem usa o SQL Server 2012, o IIF é um recurso que foi adicionado e funciona como uma alternativa às instruções 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
Você pode ter duas opções para isso realmente implementar:
Usando o IIF, que foi introduzido no SQL Server 2012:
SELECT IIF ( (Obsolete = 'N' OR InStock = 'Y'), 1, 0) AS Saleable, * FROM Product
Usando Select Case
:
SELECT CASE
WHEN Obsolete = 'N' or InStock = 'Y'
THEN 1
ELSE 0
END as Saleable, *
FROM Product
Questão:
SELECT IF(Obsolete = 'N' OR InStock = 'Y' ? 1 : 0) AS Saleable, * FROM Product
ANSI:
Select
case when p.Obsolete = 'N'
or p.InStock = 'Y' then 1 else 0 end as Saleable,
p.*
FROM
Product p;
Usar aliases - p
neste caso - ajudará a evitar problemas.
O uso do SQL CASE é como as instruções If / Else normais. Na consulta abaixo, se o valor obsoleto = 'N' ou o valor InStock = 'Y', a saída será 1. Caso contrário, a saída será 0. Em seguida, colocamos esse valor 0 ou 1 na coluna Salable.
SELECT
CASE
WHEN obsolete = 'N' OR InStock = 'Y'
THEN 1
ELSE 0
END AS Salable
, *
FROM PRODUCT
If..Then...Else..
uso de instruções da SQL
seguinte maneira ....
SELECT
CAST(
CASE WHEN Obsolete = 'N'
or InStock = 'Y' THEN ELSE 0 END AS bit
) as Saleable, *
FROM
Product
Será algo assim:
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';
Por uma questão de integridade, eu acrescentaria que o SQL usa lógica de três valores. A expressão:
obsolete = 'N' OR instock = 'Y'
Pode produzir três resultados distintos:
| 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 |
Por exemplo, se um produto é obsoleto, mas você não sabe se o produto é instock, você não sabe se o produto é vendável. Você pode escrever essa lógica de três valores da seguinte maneira:
SELECT CASE
WHEN obsolete = 'N' OR instock = 'Y' THEN 'true'
WHEN NOT (obsolete = 'N' OR instock = 'Y') THEN 'false'
ELSE NULL
END AS saleable
Depois de descobrir como ele funciona, você pode converter três resultados em dois, decidindo o comportamento de nulo. Por exemplo, isso trataria null como não vendável:
SELECT CASE
WHEN obsolete = 'N' OR instock = 'Y' THEN 'true'
ELSE 'false' -- either false or null
END AS saleable
Eu gosto do uso das instruções CASE, mas a pergunta solicitou uma instrução IF no SQL Select. O que eu usei no passado foi:
SELECT
if(GENDER = "M","Male","Female") as Gender
FROM ...
É como as instruções IF do excel ou de folhas em que há um condicional seguido pela condição verdadeira e depois pela condição falsa:
if(condition, true, false)
Além disso, você pode aninhar as instruções if (mas, em seguida, use deve usar um CASE :-)
(Nota: isso funciona no MySQLWorkbench, mas pode não funcionar em outras plataformas)
Você pode usar a declaração de caso:
Select
Case WHEN (Obsolete = 'N' or InStock = 'Y') THEN 1 ELSE 0 END Saleable,
Product.*
from Product