Как мне выполнить IF… THEN в SQL SELECT?

Как мне выполнить IF...THENв SQL SELECTзаявлении?

Например:

SELECT IF(Obsolete = 'N' OR InStock = 'Y' ? 1 : 0) AS Saleable, * FROM Product
15.09.2008 14:34:09
Вы можете взглянуть на эту ссылку . Относительно: предложений SQL WHERE: Избегайте CASE, используйте логическую логику
Somebody 14.02.2012 21:21:23
@ Somebody: не очень актуально, потому что в статье говорится об использовании логических правил перезаписи для преобразования импликации в дизъюнкцию. Подсказка - это слово «логический», то есть то, что преобразуется в истину или ложь, что не относится к проекции. TL; статья DR относится WHEREи к, CHECKно не SELECT.
onedaywhen 11.05.2016 16:06:37
Ответ @ MartinSmith самый элегантный - используйте IIF в SQL 2012+.
Murray Foxcroft 27.03.2017 13:06:02
29 ОТВЕТОВ
РЕШЕНИЕ

Этот 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
1742
3.06.2019 15:49:45
Еще одно предостережение: не заключайте условия в скобки при использовании кейса. Потребовалось немало времени, чтобы осознать это :)
Archan Mishra 13.09.2011 15:41:37
и не забывайте КОНЕЦ
Simon_Weaver 28.01.2014 10:52:37
и как немного!
Cas Bloem 22.04.2014 12:49:30
Случай, когда Else и End должны иметь параллельный отступ (вдоль одной и той же линии) - и только после этого следует отступать внутрь - лучше всего подходит для меня.
Ujjwal Singh 1.07.2014 21:24:29
@ReeveStrife Only iif SQL Server 2012+
stuartdotnet 30.05.2016 03:26:07
SELECT  
(CASE 
     WHEN (Obsolete = 'N' OR InStock = 'Y') THEN 'YES'
                                            ELSE 'NO' 
 END) as Salable
, * 
FROM Product
50
29.03.2012 12:36:04

Используйте CASE. Что-то вроде этого.

SELECT Salable =
        CASE Obsolete
        WHEN 'N' THEN 1
        ELSE 0
    END
75
15.09.2008 14:37:49
 SELECT
   CASE 
      WHEN OBSOLETE = 'N' or InStock = 'Y' THEN 'TRUE' 
      ELSE 'FALSE' 
   END AS Salable,
   * 
FROM PRODUCT
45
15.09.2008 14:37:56

Вы можете найти несколько хороших примеров в «Силах операторов SQL CASE» , и я думаю, что заявление, которое вы можете использовать, будет примерно таким (из 4guysfromrolla ):

SELECT
    FirstName, LastName,
    Salary, DOB,
    CASE Gender
        WHEN 'M' THEN 'Male'
        WHEN 'F' THEN 'Female'
    END
FROM Employees
91
24.05.2011 17:31:26
см. meta.stackexchange.com/questions/103053/… для интересного обсуждения. В двух предоставленных вами ссылках добавлен дополнительный контекст, который я поддерживаю.
Sam Saffron 19.08.2011 02:47:35

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
46
3.06.2019 15:50:53
почему бы тебе просто не сделать where Obsolete = 'N' or InStock = 'Y'и практически не разрезать "где" пополам
maksymiuk 7.06.2019 22:04:28

Используйте оператор CASE:

SELECT CASE
       WHEN (Obsolete = 'N' OR InStock = 'Y')
       THEN 'Y'
       ELSE 'N'
END as Available

etc...
24
4.11.2016 12:45:14

Ситуация в вашем случае - ваш друг, и она принимает одну из двух форм:

Простой случай:

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 в порядок по условию для действительно необычного порядка.

326
28.10.2015 00:07:31
Я знаю, что это старый, но я думаю, что следует отметить, что вы можете добавить AS Col_Nameпосле, ENDчтобы назвать результирующий столбец
Ben 18.06.2012 10:22:11
Я всегда чувствую, что 2-й проще.
Hogan 15.04.2016 20:32:58
Согласен, я почти всегда заканчиваю тем, что использую расширенный оператор case, потому что условия, на которых я хочу проверить, всегда более сложны, чем просто одна переменная. Мне также легче читать.
magnum_pi 18.05.2016 16:34:49
Хорошее объяснение обеих ситуаций, с переменной или без нее. С помощью переменной условие должно удовлетворять равенству между переменной после оператора case и той, на которой вы основываете свое условие, без переменной вы можете добавить самодостаточное условие для проверки.
Remus.A 23.02.2018 11:24:50
Мне удобнее второй вариант. Два одинаково хорошо.
Stanley Okpala Nwosa 20.10.2018 09:30:40

По этой ссылке мы можем понять 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?

45
3.06.2019 15:52:16
Это не то, что хотел запрашивающий, но очень полезно знать, что вы можете использовать операторы if вне оператора select.
Jonathan 10.04.2013 08:06:51
EXISTS хорош, потому что он выбрасывает из цикла поиска, если элемент найден. COUNT выполняется до конца строк таблицы. Ничего общего с вопросом, но кое-что, чтобы знать.
JustJohn 11.02.2016 21:12:24

С 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

Однако при таком подходе следует иногда проявлять осторожность, чтобы избежать проблем с анализом параметров .

273
3.06.2019 15:54:01
Это должно быть ответом, если вы хотите оператор IF .. then в SQL.
Mr.J 16.03.2017 03:27:52

Если вы вставляете результаты в таблицу впервые, а не переносите результаты из одной таблицы в другую, это работает в 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');
12
26.10.2012 15:30:18
теги говорят SQL Server, TSQL
Malachi 27.12.2012 15:46:27

Используйте чистую битовую логику:

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 .

24
3.06.2019 15:56:26
-1 для обфускации кода. Серьезно, это как можно дальше от WYSIWYG! Рудный нечитаемый беспорядок, и если бы мне пришлось работать над вашим кодом, я бы весь день проклинал ... извините: - /
Heliac 22.06.2013 08:47:00
@Heliac поместил свою часть в View, и ты никогда не увидишь беспорядок. Для длинных и сложных И, ИЛИ, НЕ он более читабелен, чем CASE (эта часть, конечно, за пределами cte).
Tomasito 23.06.2013 09:52:05
Я дал это +1 за опрятность, как только это в cte, но обратите внимание, что ответ в настоящее время неправильный для вопроса. Вам нужен '|' не '&'.
Mark Hurd 16.11.2016 00:19:38
Полностью согласен с @Heliac. Хотя это синтаксически правильно и работает нормально, это не так просто поддерживать. Помещение его в CTE просто переместит этот фрагмент нечитаемого кода в другое место.
objectNotFound 24.11.2017 17:04:22
Настольный метод проверки комбинации может иметь свои преимущества. Использование табличной переменной и присоединение ее к существующему запросу может обеспечить решение на основе множеств без регистра. Этот ответ является плохим примером, но сама идея таблицы имеет свои достоинства.
Suncat2000 30.11.2018 13:19:31

Для тех, кто использует SQL Server 2012, IIF - это функция, которая была добавлена ​​и работает в качестве альтернативы операторам Case.

SELECT IIF(Obsolete = 'N' OR InStock = 'Y', 1, 0) AS Salable, *
FROM   Product 
6
7.04.2014 14:16:17
Этот ответ повторяет (с меньшими подробностями) то, что уже было представлено в ответе Мартином Смитом несколько лет назад.
jk7 31.10.2018 19:44:22
SELECT CASE WHEN profile.nrefillno = 0 THEN 'N' ELSE 'R'END as newref
From profile
17
25.08.2015 09:44:46
Можете ли вы уточнить?
Peter Mortensen 3.06.2019 15:57:11
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
14
9.12.2015 12:15:36
Не могли бы вы объяснить, как это отвечает на заданный вопрос?
Guanxi 9.12.2015 13:32:05
@Guanxi: хотя и не мой ответ, «случай» обобщает «если-то-еще» (от 2 до многих случаев)
JosephDoggie 2.10.2018 16:39:15
Можете ли вы уточнить?
Peter Mortensen 3.06.2019 15:57:04

Простой оператор 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
32
3.06.2019 15:57:29
Поздно, но можно ли его использовать внутри, SELECTкак спросил ОП?
abdul qayyum 17.02.2019 10:23:07

Это не ответ, а пример использования оператора 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]
13
11.10.2016 08:00:39
Редактирование, которое переформатировало операторы Case, является хорошим и изящным и делает его более понятным, но SQL все равно будет объединяться в представлении, которое его использует.
JustJohn 12.10.2016 16:30:01
Я просто странствую, почему CASEменя проголосовали и отметили как ответ вместо того, IFкоторый должен был быть ответом, как этот, это все еще CASEутверждение, а не ответ IF.
Mr.J 22.03.2017 07:16:38
@ Mr.J: хотя и не мой ответ, «случай» обобщает «если-то-еще» (от 2 до многих случаев)
JosephDoggie 2.10.2018 16:40:51

В SQL Server 2012 была добавлена новая функция IIF (которую мы можем просто использовать):

SELECT IIF ( (Obsolete = 'N' OR InStock = 'Y'), 1, 0) AS Saleable, * FROM Product
24
30.09.2017 00:12:39
Этот ответ повторяет (с меньшими подробностями) то, что уже было представлено в ответе Мартином Смитом несколько лет назад.
jk7 31.10.2018 19:47:50
@ jk7 это был первый ответ на вопрос.
sandeep rawat 1.11.2018 02:46:14
Не из того, что я вижу. Там написано, что ваш ответ был опубликован 26 апреля 16 года, а ответ Мартина - 20 июля 2011 года.
jk7 2.11.2018 14:40:53
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' )
19
11.05.2016 15:56:30
  SELECT IIF(Obsolete = 'N' OR InStock = 'Y',1,0) AS Saleable, * FROM Product
6
30.11.2016 11:05:06
Привет Сурджит Сингх Бишт; ваш код может быть верным, но с некоторым контекстом это даст лучший ответ; Например, вы могли бы объяснить, как и почему это предлагаемое изменение решит проблему спрашивающего, возможно, включив ссылку на соответствующую документацию. Это сделало бы его более полезным для них, а также более полезным для других читателей сайта, которые ищут решения подобных проблем.
Vince Bowdren 30.11.2016 16:27:31
Этот ответ не добавляет ничего нового. Фактически, эта та же самая линия была частью принятого ответа более 5 лет .
S.L. Barth - Reinstate Monica 30.11.2016 19:20:48
Кроме того, важно отметить, что IIF применяется только для SQL Server, начиная с 2012 года
Ivan Rascon 26.01.2017 16:24:03
SELECT CASE WHEN Obsolete = 'N' or InStock = 'Y' THEN 1 ELSE 0 
             END AS Saleable, * 
FROM Product
9
8.08.2017 21:33:52

В качестве альтернативного решения 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
11
3.06.2019 16:00:45
Salable используется в где условие в запросе?
Bhavin Thummar 8.11.2019 12:14:43
Это можно использовать в тех условиях, где.
Serkan Arslan 8.11.2019 12:36:49
SELECT 
  CAST(
    CASE WHEN Obsolete = 'N' 
    or InStock = 'Y' THEN ELSE 0 END AS bit
  ) as Saleable, * 
FROM 
  Product
2
6.03.2019 07:49:52
Из обзора: добро пожаловать в стек переполнения! Пожалуйста, не отвечайте только с исходным кодом. Попробуйте дать хорошее описание того, как работает ваше решение. Смотрите: Как мне написать хороший ответ? , Спасибо
sɐunıɔןɐqɐp 8.10.2018 06:52:02
Я думаю, вы обнаружите, что это не выполняется, потому что отсутствует какой-либо вывод после ключевого слова THEN.
Dodecaphone 5.04.2019 14:00:58
Можете ли вы уточнить?
Peter Mortensen 3.06.2019 16:01:13

Вопрос:

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в этом случае - поможет предотвратить проблемы.

4
6.03.2019 07:32:25

У вас может быть два варианта для реализации:

  1. Использование IIF, которое появилось в SQL Server 2012:

    SELECT IIF ( (Obsolete = 'N' OR InStock = 'Y'), 1, 0) AS Saleable, * FROM Product
  2. Использование Select Case:

    SELECT CASE
        WHEN Obsolete = 'N' or InStock = 'Y'
            THEN 1
            ELSE 0
        END as Saleable, *
        FROM Product
4
3.06.2019 16:02:11

Это будет что-то вроде этого:

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;
2
31.10.2019 12:06:34
Можем ли мы использовать значение количества в тексте условия в запросе? например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';
Bhavin Thummar 8.11.2019 12:14:03

Для полноты картины я бы добавил, что в 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. Например, это будет относиться к нулю как к не продаваемому:

SELECT CASE
           WHEN obsolete = 'N' OR instock = 'Y' THEN 'true'
           ELSE 'false' -- either false or null
       END AS saleable
1
28.11.2019 10:17:11

Использование SQL CASE аналогично обычным операторам If / Else. В нижеследующем запросе, если устаревшее значение = 'N' или If InStock value = 'Y', тогда Output будет 1. В противном случае, вывод будет 0. Затем мы помещаем это 0 или 1 значение в столбец Salable.

SELECT
      CASE 
        WHEN obsolete = 'N' OR InStock = 'Y' 
        THEN 1 
        ELSE 0 
      END AS Salable
      , * 
FROM PRODUCT
2
18.02.2020 11:45:44
Звучит хорошо. Может быть, слово или два, чтобы объяснить это?
JQSOFT 18.02.2020 11:11:13
Это как обычные операторы If / Else. Если устаревшее значение = 'N' или If InStock value = 'Y', то выходное значение будет равно 1. В противном случае выходное значение будет равно 0.
Tharuka 18.02.2020 11:22:04
Спасибо. Пожалуйста, отредактируйте свой пост, чтобы добавить это объяснение. Как: Использование If..Then...Else..заявления в SQLследующем ....
JQSOFT 18.02.2020 11:39:26

Мне нравится использование операторов CASE, но вопрос, заданный для оператора IF в SQL Select. То, что я использовал в прошлом, было:

SELECT

   if(GENDER = "M","Male","Female") as Gender

FROM ...

Это как операторы Excel или листов IF, где есть условное условие, за которым следует истинное условие, а затем ложное условие:

if(condition, true, false)

Кроме того, вы можете вкладывать операторы if (но для использования следует использовать CASE :-)

(Примечание: это работает в MySQLWorkbench, но может не работать на других платформах)

0
9.04.2020 23:12:58