Как выполнить IF...THEN
в операторе SQL SELECT
?
Например:
SELECT IF(Obsolete = 'N' OR InStock = 'Y' ? 1 : 0) AS Saleable, * FROM Product
Как выполнить 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, который также доступен в доступе (на это указывает Мартин Смит <65089273265027>):
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.
Спасибо, сэр, СЛУЧАЙ КОГДА был тем, что я искал!
SELECT
if((obsolete = 'N' OR instock = 'Y'), 1, 0) AS saleable, *
FROM
product;
Мне нравится использование операторов CASE, но вопрос задан для оператора IF в SQL Select. Раньше я использовал:
SELECT
if(GENDER = "M","Male","Female") as Gender
FROM ...
Это похоже на операторы IF в Excel или Sheet, где за условным условием следует истинное, а затем ложное условие:
if(condition, true, false)
Кроме того, вы можете вкладывать операторы if (но тогда используйте CASE :-)
(Примечание: это работает в MySQLWorkbench, но может не работать на других платформах)
IF FUNCTION Кажется, присутствует в MySQL, но не в MSSQL, В MSSQL IIF может использоваться с версии 2012.
Использование 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
следующим образом ....
Для полноты я бы добавил, что 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
Это будет примерно так:
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';
У вас может быть два варианта реализации:
Использование 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 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
- поможет предотвратить проблемы.
SELECT
CAST(
CASE WHEN Obsolete = 'N'
or InStock = 'Y' THEN ELSE 0 END AS bit
) as Saleable, *
FROM
Product
Из отзыва: Добро пожаловать в Stack Overflow! Пожалуйста, не отвечайте только исходным кодом. Постарайтесь дать хорошее описание того, как работает ваше решение. См .: Как мне написать хороший ответ ?. Спасибо
Я думаю, вы обнаружите, что это не выполняется, потому что отсутствует какой-либо вывод, следующий за ключевым словом THEN.
В качестве альтернативы оператору 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
Привет Сурджит Сингх Бишт; ваш код может быть правильным, но с некоторым контекстом он даст лучший ответ; например, вы могли бы объяснить, как и почему это предлагаемое изменение решит проблему, задавшую вопрос, возможно, включая ссылку на соответствующую документацию. Это сделало бы его более полезным для них, а также для других читателей сайта, которые ищут решения аналогичных проблем.
Этот ответ не добавляет ничего нового. Фактически, эта же самая линия была частью принятого ответа более 5 лет.
Кроме того, важно отметить, что IIF применяется только для SQL Server, начиная с 2012 года.
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' )
Новая функция, IIF (которую мы можем просто использовать), была добавлена в SQL Server 2012:
SELECT IIF ( (Obsolete = 'N' OR InStock = 'Y'), 1, 0) AS Saleable, * FROM Product
Этот ответ повторяет (с меньшими подробностями) то, что уже было предоставлено в ответе Мартина Смита несколько лет назад.
@ jk7 это был первый ответ на вопрос.
Не из того, что я вижу. В нем говорится, что ваш ответ был опубликован 26 апреля 2016 года, а ответ Мартина - 20 июля 2011 года.
Это не ответ, а просто пример оператора 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: хотя это и не мой ответ, «случай» обобщает «если-то-еще» (от двух до многих)
Простой оператор 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 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: хотя это и не мой ответ, «случай» обобщает «если-то-еще» (от двух до многих)
SELECT CASE WHEN profile.nrefillno = 0 THEN 'N' ELSE 'R'END as newref
From profile
Для тех, кто использует SQL Server 2012, IIF - это функция, которая была добавлена и работает как альтернатива операторам Case.
SELECT IIF(Obsolete = 'N' OR InStock = 'Y', 1, 0) AS Salable, *
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. Затем используйте побитовые операторы.
Это самый метод WYSIWYG.
-1 для обфускации кода. Серьезно, это настолько далеко от WYSIWYG, насколько это возможно! Рыжий нечитаемый беспорядок, и если бы мне пришлось поработать над вашим кодом, я бы весь день ругался ... извините: - /
@Heliac поместил cte часть в View, и вы никогда не увидите беспорядка. Для длинных и сложных AND, OR, NOT он более читабелен, чем CASE (эта часть, конечно, вне cte).
Я дал ему +1 за аккуратность, как только он находится в cte, но обратите внимание, что в настоящее время ответ на вопрос неверен. Вам нужен символ '|' не "&".
Полностью согласен с @Heliac. Хотя он синтаксически правильный и отлично работает, его нелегко поддерживать. Помещение его в CTE просто переместит этот нечитаемый код в другое место.
Табличный метод проверки комбинации может иметь свои преимущества. Использование табличной переменной и ее присоединение к существующему запросу может обеспечить решение на основе набора без учета регистра. Этот ответ - плохой пример, но сама идея таблицы имеет свои достоинства.
Если вы впервые вставляете результаты в таблицу, а не переносите результаты из одной таблицы в другую, это работает в 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
В 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
Это должен быть ответ, если вам нужен оператор IF .. then в SQL.
Из этой ссылки, мы можем понять 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 вне оператора select.
EXISTS хорош, потому что он выпадает из цикла поиска, если элемент найден. COUNT выполняется до конца строк таблицы. Ничего общего с вопросом, но кое-что нужно знать.
Оператор 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 в предложении order by для действительно необычного упорядочивания.
Я знаю, что это старый, но я думаю, что следует отметить, что вы можете добавить AS Col_Name
после END
, чтобы назвать результирующий столбец
Мне всегда кажется, что второй проще.
Согласен, я почти всегда использую расширенный оператор case, потому что условия, которые я хочу протестировать, всегда сложнее, чем просто одна переменная. Мне также легче читать.
Хорошее объяснение обеих ситуаций, с переменной или без нее. С переменной условие должно удовлетворять равенству между переменной после оператора case и той, на которой вы основываете свое условие, без переменной вы можете добавить самодостаточное условие для проверки.
Я не думаю, что это личное предпочтение выбора одного по сравнению с другим .. его вариант использования: D
Используйте оператор CASE:
SELECT CASE
WHEN (Obsolete = 'N' OR InStock = 'Y')
THEN 'Y'
ELSE 'N'
END as Available
etc...
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'
и практически не разрезать где пополам
Вы можете найти несколько хороших примеров в Сила SQL CASE-выражений , и я думаю, что вы можете использовать такой оператор (от 4guysfromrol>):
SELECT
FirstName, LastName,
Salary, DOB,
CASE Gender
WHEN 'M' THEN 'Male'
WHEN 'F' THEN 'Female'
END
FROM Employees
см .: meta.stackexchange.com/questions/103053/… для интересного обсуждения. Две предоставленные вами ссылки добавляют дополнительный контекст, который я поддерживаю.
Ссылка действительно полезна и настоятельно рекомендуется в случае дополнительных деталей.
SELECT
CASE
WHEN OBSOLETE = 'N' or InStock = 'Y' THEN 'TRUE'
ELSE 'FALSE'
END AS Salable,
*
FROM PRODUCT
Вы можете взглянуть на эту ссылку. Что касается предложений SQL WHERE: избегайте CASE, используйте логическую логику
@Somebody: не очень актуально, потому что в статье говорится об использовании правил логической перезаписи для преобразования импликации в дизъюнкцию. Ключом к разгадке является слово «логический», то есть то, что разрешается как истинное или ложное, что не относится к проекции. Статья TL; DR применяется к
WHERE
иCHECK
, но не кSELECT
.Ответ @MartinSmith самый элегантный - используйте IIF в SQL 2012+.