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

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

Например:

SELECT IF(Obsolete = 'N' OR InStock = 'Y' ? 1 : 0) AS Saleable, * FROM Product

Вы можете взглянуть на этот связь. Что касается предложений SQL WHERE: избегайте CASE, используйте логическую логику

Somebody 15.02.2012 01:21

@Somebody: не очень актуально, потому что в статье говорится об использовании правил логической перезаписи для преобразования импликации в дизъюнкцию. Ключом к разгадке является слово «логический», то есть то, что разрешается в истинное или ложное, что не относится к проекции. Статья TL; DR относится к WHERE и CHECK, но не к SELECT.

onedaywhen 11.05.2016 19:06

Ответ @MartinSmith самый элегантный - используйте IIF в SQL 2012+.

Murray Foxcroft 27.03.2017 16:06
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
1 587
3
3 834 159
31
Перейти к ответу Данный вопрос помечен как решенный

Ответы 31

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. Потребовалось довольно много времени, чтобы осознать это :)

Archan Mishra 13.09.2011 19:41

и не забывай КОНЕЦ

Simon_Weaver 28.01.2014 14:52

Хотя это работает, использование функции IFF () будет лучшим ответом.

Gerrie Pretorius 09.10.2015 18:42

@ReeveStrife Вы имеете в виду IIF()msdn.microsoft.com/en-us/library/…

katalin_2003 30.03.2016 18:03

Только @ReeveStrife iif SQL Server 2012+

stuartdotnet 30.05.2016 06:26

@ArchanMishra Привет, Арчан, не могли бы вы объяснить мне, почему вы не должны заключать свои условия?

Bernard Walters 16.01.2017 15:30

Остерегайтесь грязных секретов CASE / IIF: sqlperformance.com/2014/06/t-sql-queries/…

user170442 27.01.2017 15:21

@ArchanMishra, ты можешь. Я думал, он имел в виду, что это замедлит процесс, но нет. Вы можете использовать квадратные скобки в SQL Server столько раз, сколько захотите, если это логично для SQL.

Fandango68 21.03.2017 06:22

@DarrelMiller вы, вероятно, можете вернуть TRUE или FALSE в операторе CASE и избежать CAST, не уверен, работает ли он на SQL Server, но я думаю, что это SQL. Я никогда не видел ничего подобного

Abdul Ahad 20.01.2018 16:44

Вы можете найти несколько хороших примеров в Возможности операторов 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/… для интересного обсуждения. Две предоставленные вами ссылки добавляют дополнительный контекст, который я поддерживаю.

Sam Saffron 19.08.2011 06:47

Ссылка действительно полезна и настоятельно рекомендуется в случае дополнительных деталей.

baymax 07.12.2016 17:56

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' и практически не разрезать где пополам

maksymiuk 08.06.2019 01:04

Используйте оператор 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, чтобы назвать результирующий столбец

Ben 18.06.2012 14:22

Мне всегда кажется, что второй проще.

Hogan 15.04.2016 23:32

Согласен, я почти всегда использую расширенный оператор case, потому что условия, которые я хочу протестировать, всегда сложнее, чем просто одна переменная. Мне также легче читать.

magnum_pi 18.05.2016 19:34

Хорошее объяснение обеих ситуаций, с переменной или без нее. С переменной условие должно удовлетворять равенству между переменной после оператора case и той, на которой вы основываете свое условие, без переменной вы можете добавить самодостаточное условие для проверки.

Remus.A 23.02.2018 14:24

Мне удобнее второй вариант. Оба одинаково хороши.

Stanley Okpala Nwosa 20.10.2018 12:30

Я не думаю, что это личное предпочтение выбора одного по сравнению с другим .. его вариант использования: D

Michael Fronzek 25.11.2020 14:20

Из эта ссылка мы можем понять 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 за пределами как оператор выбора.

Jonathan 10.04.2013 12:06

EXISTS хорош, потому что он выпадает из цикла поиска, если элемент найден. COUNT выполняется до конца строк таблицы. Ничего общего с вопросом, но кое-что нужно знать.

JustJohn 12.02.2016 00:12

Начиная с 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.

Mr.J 16.03.2017 06:27

Если вы впервые вставляете результаты в таблицу, а не переносите результаты из одной таблицы в другую, это работает в 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

Malachi 27.12.2012 19:46

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

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, насколько это возможно! Рыжий нечитаемый беспорядок, и если бы мне пришлось поработать над вашим кодом, я бы весь день ругался ... извините: - /

Riegardt Steyn 22.06.2013 12:47

@Heliac поместил cte часть в View, и вы никогда не увидите беспорядка. Для длинных и сложных AND, OR, NOT он более читабелен, чем CASE (эта часть, конечно, вне cte).

Tomasito 23.06.2013 13:52

Я дал ему +1 за аккуратность, как только он находится в cte, но обратите внимание, что в настоящее время ответ на вопрос неверен. Вам нужен '|' не "&".

Mark Hurd 16.11.2016 03:19

Полностью согласен с @Heliac. Хотя он синтаксически правильный и отлично работает, его нелегко поддерживать. Помещение его в CTE просто переместит этот нечитаемый код в другое место.

objectNotFound 24.11.2017 20:04

Табличный метод проверки комбинации может иметь свои преимущества. Использование табличной переменной и присоединение ее к существующему запросу может обеспечить решение на основе набора без случая. Этот ответ - плохой пример, но сама идея таблицы имеет свои достоинства.

Suncat2000 30.11.2018 16:19

Срок действия ссылки NULLIF от Microsoft истек. вот новая рабочая ссылка: docs.microsoft.com/en-us/sql/t-sql/language-elements/… Обновлено в ответе.

abdul qayyum 17.02.2019 13:18

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

SELECT IIF(Obsolete = 'N' OR InStock = 'Y', 1, 0) AS Salable, *
FROM   Product 

Этот ответ повторяет (с меньшей детализацией) то, что было уже предоставлено в ответе Мартина Смита несколько лет назад.

jk7 31.10.2018 22:44

SELECT CASE WHEN profile.nrefillno = 0 THEN 'N' ELSE 'R'END as newref
From profile

Вы можете уточнить?

Peter Mortensen 03.06.2019 18:57

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 09.12.2015 16:32

@Guanxi: хотя это и не мой ответ, «случай» обобщает «если-то-еще» (от двух до многих)

JosephDoggie 02.10.2018 19:39

Вы можете уточнить?

Peter Mortensen 03.06.2019 18:57

Простой оператор 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?

abdul qayyum 17.02.2019 13:23

Это не ответ, это просто пример оператора 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 все равно будет скучать в представлении, которое его использует.

JustJohn 12.10.2016 19:30

Я просто блуждаю, почему CASE получил одобрение и помечен как ответ вместо IF, который должен был быть ответом, как этот, это все еще заявление CASE, а не IF.

Mr.J 22.03.2017 10:16

@ Mr.J: хотя и не мой ответ, «случай» обобщает «если-то-еще» (от двух до многих)

JosephDoggie 02.10.2018 19:40

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

SELECT IIF ( (Obsolete = 'N' OR InStock = 'Y'), 1, 0) AS Saleable, * FROM Product

Этот ответ повторяет (с меньшей детализацией) то, что было уже предоставлено в ответе Мартина Смита несколько лет назад.

jk7 31.10.2018 22:47

@ jk7 это был первый ответ на вопрос.

sandeep rawat 01.11.2018 05:46

Не то, что я вижу. В нем говорится, что ваш ответ был опубликован 26 апреля 2016 года, а ответ Мартина - 20 июля 2011 года.

jk7 02.11.2018 17:40

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

Привет Сурджит Сингх Бишт; ваш код может быть правильным, но с некоторым контекстом он даст лучший ответ; например, вы можете объяснить, как и почему это предлагаемое изменение решит проблему, задавшую вопрос, возможно, включая ссылку на соответствующую документацию. Это сделало бы его более полезным для них, а также для других читателей сайта, которые ищут решения аналогичных проблем.

Vince Bowdren 30.11.2016 19:27

Этот ответ не добавляет ничего нового. Фактически, эта же строка была частью принятого ответа более 5 лет.

S.L. Barth - Reinstate Monica 30.11.2016 22:20

Кроме того, важно отметить, что IIF применяется только для SQL Server, начиная с 2012 года.

Ivan Rascon 26.01.2017 19:24

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

Где используется условие продажи в запросе?

Bhavin Thummar 08.11.2019 15:14

Его можно использовать в любом состоянии.

Serkan Arslan 08.11.2019 15:36

SELECT 
  CAST(
    CASE WHEN Obsolete = 'N' 
    or InStock = 'Y' THEN ELSE 0 END AS bit
  ) as Saleable, * 
FROM 
  Product

Из отзыва: Добро пожаловать в Stack Overflow! Пожалуйста, не отвечайте только исходным кодом. Постарайтесь дать хорошее описание того, как работает ваше решение. См .: Как мне написать хороший ответ?. Спасибо

sɐunıɔןɐqɐp 08.10.2018 09:52

Я думаю, вы обнаружите, что это не выполняется, потому что отсутствует какой-либо вывод, следующий за ключевым словом THEN.

Dodecaphone 05.04.2019 17:00

Вы можете уточнить?

Peter Mortensen 03.06.2019 19:01

Вопрос:

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

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

  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
    

Будет примерно так:

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';

Bhavin Thummar 08.11.2019 15:14

Для полноты я бы добавил, что 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.

Tharuka 18.02.2020 14:22

Спасибо. Пожалуйста, Редактировать свой пост, чтобы добавить это объяснение. Например: использование заявлений If..Then...Else.. в SQL следующим образом ....

user10216583 18.02.2020 14:39

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

SELECT

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

FROM ...

Это похоже на операторы ЕСЛИ в Excel или листах, где за условным условием следует истинное условие, а затем ложное условие:

if (condition, true, false)

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

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

ЕСЛИ ФУНКЦИЯ It seems present in MySQL, but not in MSSQL, In MSSQL IIF can be used since version 2012.
Luuk 01.08.2020 12:15

Вы можете использовать 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;

Другие вопросы по теме