Как мне выполнить IF ...THEN в SQL SELECT?
-
09-06-2019 - |
Вопрос
Как мне выполнить IF...THEN
в SQL SELECT
заявление?
Например:
SELECT IF(Obsolete = 'N' OR InStock = 'Y' ? 1 : 0) AS Saleable, * FROM Product
Решение
Тот Самый CASE
оператор является наиболее близким к IF в SQL и поддерживается во всех версиях 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 заявление, которое также доступно в доступ (указано Мартин Смит):
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 для действительно необычного упорядочения.
Начиная с 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
Вы можете найти несколько приятных примеров в Сила инструкций SQL CASE, и я думаю, что утверждение, которое вы можете использовать, будет примерно таким (из 4 парня из роллы):
SELECT
FirstName, LastName,
Salary, DOB,
CASE Gender
WHEN 'M' THEN 'Male'
WHEN 'F' THEN 'Female'
END
FROM Employees
ПРИМЕР использования.Что-то вроде этого.
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
SELECT
CASE
WHEN OBSOLETE = 'N' or InStock = 'Y' THEN 'TRUE'
ELSE 'FALSE'
END AS Salable,
*
FROM PRODUCT
Microsoft SQL Server (T-SQL)
В select
, использовать:
select case when Obsolete = 'N' or InStock = 'Y' then 'YES' else 'NO' end
В where
оговорка, использование:
where 1 = case when Obsolete = 'N' or InStock = 'Y' then 1 else 0 end
От эта ссылка, мы можем понять 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?
Простой оператор if-else в SQL Server:
DECLARE @val INT;
SET @val = 15;
IF @val < 25
PRINT 'Hi Ravi Anand';
ELSE
PRINT 'By Ravi Anand.';
GO
Вложенный оператор If ...else в 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
Используйте оператор CASE:
SELECT CASE
WHEN (Obsolete = 'N' OR InStock = 'Y')
THEN 'Y'
ELSE 'N'
END as Available
etc...
Новая функция, IIF (который мы можем просто использовать), был добавлен в SQL Server 2012:
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
для выбранных условий.А вот и двое НУЛЛИФ:
for true: ISNULL(NULLIF(p.[Instock], 'Y'), 1)
for false: ISNULL(NULLIF(p.[Instock], 'N'), 0)
в сочетании друг с другом получается 1 или 0.Следующее использование побитовые операторы.
Это самый 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
Это не ответ, просто пример инструкции 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]
Если вы впервые вставляете результаты в таблицу, а не переносите их из одной таблицы в другую, это работает в 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
SELECT IIF(Obsolete = 'N' OR InStock = 'Y',1,0) AS Saleable, * FROM Product
Для тех, кто использует SQL Server 2012, IIF - это добавленная функция, которая работает как альтернатива операторам Case.
SELECT IIF(Obsolete = 'N' OR InStock = 'Y', 1, 0) AS Salable, *
FROM Product
Вопрос:
SELECT IF(Obsolete = 'N' OR InStock = 'Y' ? 1 : 0) AS Saleable, * FROM Product
АНСИ:
Select
case when p.Obsolete = 'N'
or p.InStock = 'Y' then 1 else 0 end as Saleable,
p.*
FROM
Product p;
Использование псевдонимов -- p
в этом случае - поможет предотвратить проблемы.
У вас может быть два варианта для реальной реализации этого:
Используя IIF, который был представлен в SQL Server 2012:
SELECT IIF ( (Obsolete = 'N' OR InStock = 'Y'), 1, 0) AS Saleable, * FROM Product
Используя
Select Case
:SELECT CASE WHEN Obsolete = 'N' or InStock = 'Y' THEN 1 ELSE 0 END as Saleable, * FROM Product
SELECT
CAST(
CASE WHEN Obsolete = 'N'
or InStock = 'Y' THEN ELSE 0 END AS bit
) as Saleable, *
FROM
Product