Как выполнить IF...THEN в заявлении SQL SELECT?
Например:
SELECT IF(Obsolete = 'N' OR InStock = 'Y' ? 1 : 0) AS Saleable, * FROM Product
@Somebody: не очень актуально, потому что в статье говорится об использовании правил логической перезаписи для преобразования импликации в дизъюнкцию. Ключом к разгадке является слово «логический», то есть то, что разрешается в истинное или ложное, что не относится к проекции. Статья TL; DR относится к WHERE и CHECK, но не к SELECT.
Ответ @MartinSmith самый элегантный - используйте IIF в SQL 2012+.


SELECT
(CASE
WHEN (Obsolete = 'N' OR InStock = 'Y') THEN 'YES'
ELSE 'NO'
END) as Salable
, *
FROM Product
Используйте CASE. Что-то вроде этого.
SELECT Salable =
CASE Obsolete
WHEN 'N' THEN 1
ELSE 0
END
SELECT
CASE
WHEN OBSOLETE = 'N' or InStock = 'Y' THEN 'TRUE'
ELSE 'FALSE'
END AS Salable,
*
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
Еще одно предостережение: не заключайте ваши условия в скобки при использовании case. Потребовалось довольно много времени, чтобы осознать это :)
и не забывай КОНЕЦ
Хотя это работает, использование функции IFF () будет лучшим ответом.
@ReeveStrife Вы имеете в виду IIF()msdn.microsoft.com/en-us/library/…
Только @ReeveStrife iif SQL Server 2012+
@ArchanMishra Привет, Арчан, не могли бы вы объяснить мне, почему вы не должны заключать свои условия?
Остерегайтесь грязных секретов CASE / IIF: sqlperformance.com/2014/06/t-sql-queries/…
@ArchanMishra, ты можешь. Я думал, он имел в виду, что это замедлит процесс, но нет. Вы можете использовать квадратные скобки в SQL Server столько раз, сколько захотите, если это логично для SQL.
@DarrelMiller вы, вероятно, можете вернуть TRUE или FALSE в операторе CASE и избежать CAST, не уверен, работает ли он на SQL Server, но я думаю, что это SQL. Я никогда не видел ничего подобного
Вы можете найти несколько хороших примеров в Возможности операторов SQL CASE, и я думаю, что оператор, который вы можете использовать, будет примерно таким (из 4парни):
SELECT
FirstName, LastName,
Salary, DOB,
CASE Gender
WHEN 'M' THEN 'Male'
WHEN 'F' THEN 'Female'
END
FROM Employees
см .: meta.stackexchange.com/questions/103053/… для интересного обсуждения. Две предоставленные вами ссылки добавляют дополнительный контекст, который я поддерживаю.
Ссылка действительно полезна и настоятельно рекомендуется в случае дополнительных деталей.
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
почему бы вам просто не сделать where Obsolete = 'N' or InStock = 'Y' и практически не разрезать где пополам
Используйте оператор CASE:
SELECT CASE
WHEN (Obsolete = 'N' OR InStock = 'Y')
THEN 'Y'
ELSE 'N'
END as Available
etc...
Оператор case - ваш друг в этой ситуации и принимает одну из двух форм:
Простой случай:
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 в порядке за предложением, чтобы упорядочить их по-настоящему необычно.
Я знаю, что это старый, но я думаю, что следует отметить, что вы можете добавить AS Col_Name после END, чтобы назвать результирующий столбец
Мне всегда кажется, что второй проще.
Согласен, я почти всегда использую расширенный оператор case, потому что условия, которые я хочу протестировать, всегда сложнее, чем просто одна переменная. Мне также легче читать.
Хорошее объяснение обеих ситуаций, с переменной или без нее. С переменной условие должно удовлетворять равенству между переменной после оператора case и той, на которой вы основываете свое условие, без переменной вы можете добавить самодостаточное условие для проверки.
Мне удобнее второй вариант. Оба одинаково хороши.
Я не думаю, что это личное предпочтение выбора одного по сравнению с другим .. его вариант использования: D
Из эта ссылка мы можем понять 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 за пределами как оператор выбора.
EXISTS хорош, потому что он выпадает из цикла поиска, если элемент найден. COUNT выполняется до конца строк таблицы. Ничего общего с вопросом, но кое-что нужно знать.
Начиная с SQL Server 2012 вы можете использовать для этого Функция IIF.
SELECT IIF(Obsolete = 'N' OR InStock = 'Y', 1, 0) AS Salable, *
FROM Product
По сути, это просто сокращенный (хотя и не стандартный SQL) способ написания CASE.
Я предпочитаю лаконичность по сравнению с расширенной версией 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.
IF @IncludeExtendedInformation = 1
BEGIN
SELECT A,B,C,X,Y,Z
FROM T
END
ELSE
BEGIN
SELECT A,B,C
FROM T
END
Это должен быть ответ, если вам нужен оператор IF .. then в SQL.
Если вы впервые вставляете результаты в таблицу, а не переносите результаты из одной таблицы в другую, это работает в 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');
теги говорят SQL Server, TSQL
Используйте чистую битовую логику:
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. Затем используйте побитовые операторы.
Это самый WYSIWYG метод.
-1 для обфускации кода. Серьезно, это настолько далеко от WYSIWYG, насколько это возможно! Рыжий нечитаемый беспорядок, и если бы мне пришлось поработать над вашим кодом, я бы весь день ругался ... извините: - /
@Heliac поместил cte часть в View, и вы никогда не увидите беспорядка. Для длинных и сложных AND, OR, NOT он более читабелен, чем CASE (эта часть, конечно, вне cte).
Я дал ему +1 за аккуратность, как только он находится в cte, но обратите внимание, что в настоящее время ответ на вопрос неверен. Вам нужен '|' не "&".
Полностью согласен с @Heliac. Хотя он синтаксически правильный и отлично работает, его нелегко поддерживать. Помещение его в CTE просто переместит этот нечитаемый код в другое место.
Табличный метод проверки комбинации может иметь свои преимущества. Использование табличной переменной и присоединение ее к существующему запросу может обеспечить решение на основе набора без случая. Этот ответ - плохой пример, но сама идея таблицы имеет свои достоинства.
Срок действия ссылки NULLIF от Microsoft истек. вот новая рабочая ссылка: docs.microsoft.com/en-us/sql/t-sql/language-elements/… Обновлено в ответе.
Для тех, кто использует SQL Server 2012, IIF - это функция, которая была добавлена и работает как альтернатива операторам Case.
SELECT IIF(Obsolete = 'N' OR InStock = 'Y', 1, 0) AS Salable, *
FROM Product
Этот ответ повторяет (с меньшей детализацией) то, что было уже предоставлено в ответе Мартина Смита несколько лет назад.
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
Не могли бы вы пояснить, как это отвечает на заданный вопрос?
@Guanxi: хотя это и не мой ответ, «случай» обобщает «если-то-еще» (от двух до многих)
Вы можете уточнить?
Простой оператор 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
Поздно, но можно ли его использовать внутри SELECT, как спросил OP?
Это не ответ, это просто пример оператора 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, прекрасна и изящна и делает ее более понятной, но SQL все равно будет скучать в представлении, которое его использует.
Я просто блуждаю, почему CASE получил одобрение и помечен как ответ вместо IF, который должен был быть ответом, как этот, это все еще заявление CASE, а не IF.
@ Mr.J: хотя и не мой ответ, «случай» обобщает «если-то-еще» (от двух до многих)
В SQL Server 2012 была добавлена новая функция ЕСЛИ (которую мы можем просто использовать):
SELECT IIF ( (Obsolete = 'N' OR InStock = 'Y'), 1, 0) AS Saleable, * FROM Product
Этот ответ повторяет (с меньшей детализацией) то, что было уже предоставлено в ответе Мартина Смита несколько лет назад.
@ jk7 это был первый ответ на вопрос.
Не то, что я вижу. В нем говорится, что ваш ответ был опубликован 26 апреля 2016 года, а ответ Мартина - 20 июля 2011 года.
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 IIF(Obsolete = 'N' OR InStock = 'Y',1,0) AS Saleable, * FROM Product
Привет Сурджит Сингх Бишт; ваш код может быть правильным, но с некоторым контекстом он даст лучший ответ; например, вы можете объяснить, как и почему это предлагаемое изменение решит проблему, задавшую вопрос, возможно, включая ссылку на соответствующую документацию. Это сделало бы его более полезным для них, а также для других читателей сайта, которые ищут решения аналогичных проблем.
Этот ответ не добавляет ничего нового. Фактически, эта же строка была частью принятого ответа более 5 лет.
Кроме того, важно отметить, что IIF применяется только для SQL Server, начиная с 2012 года.
SELECT CASE WHEN Obsolete = 'N' or InStock = 'Y' THEN 1 ELSE 0
END AS Saleable, *
FROM Product
В качестве альтернативы оператору 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
CAST(
CASE WHEN Obsolete = 'N'
or InStock = 'Y' THEN ELSE 0 END AS bit
) as Saleable, *
FROM
Product
Из отзыва: Добро пожаловать в Stack Overflow! Пожалуйста, не отвечайте только исходным кодом. Постарайтесь дать хорошее описание того, как работает ваше решение. См .: Как мне написать хороший ответ?. Спасибо
Я думаю, вы обнаружите, что это не выполняется, потому что отсутствует какой-либо вывод, следующий за ключевым словом THEN.
Вы можете уточнить?
Вопрос:
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;
Использование псевдонимов - в данном случае 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 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;
Можем ли мы использовать значение QuantityText в условии where в запросе? например 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
Использование SQL CASE похоже на обычные операторы If / Else. В запросе ниже, если устаревшее значение = 'N' или если значение InStock = 'Y', то вывод будет 1. В противном случае вывод будет 0. Затем мы помещаем это значение 0 или 1 в столбец «Продажная».
SELECT
CASE
WHEN obsolete = 'N' OR InStock = 'Y'
THEN 1
ELSE 0
END AS Salable
, *
FROM PRODUCT
Это похоже на обычные операторы If / Else. Если устаревшее значение = 'N' или если значение InStock = 'Y', тогда вывод будет 1. В противном случае вывод будет 0.
Спасибо. Пожалуйста, Редактировать свой пост, чтобы добавить это объяснение. Например: использование заявлений If..Then...Else.. в SQL следующим образом ....
Мне нравится использование операторов CASE, но вопрос задан для оператора IF в SQL Select. То, что я использовал в прошлом, было:
SELECT
if (GENDER = "M","Male","Female") as Gender
FROM ...
Это похоже на операторы ЕСЛИ в Excel или листах, где за условным условием следует истинное условие, а затем ложное условие:
if (condition, true, false)
Кроме того, вы можете вкладывать операторы if (но тогда используйте CASE :-)
(Примечание: это работает в MySQLWorkbench, но может не работать на других платформах)
Вы можете использовать Case Statement:
Select
Case WHEN (Obsolete = 'N' or InStock = 'Y') THEN 1 ELSE 0 END Saleable,
Product.*
from Product
SELECT
if ((obsolete = 'N' OR instock = 'Y'), 1, 0) AS saleable, *
FROM
product;
Вы можете взглянуть на этот связь. Что касается предложений SQL WHERE: избегайте CASE, используйте логическую логику