MySQL IF ELSEIF в запросе выбора


81

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

 select id, 
    (SELECT 
    IF(qty_1<='23',price,1)
    ELSEIF(('23'>qty_1 && qty_2<='23'),price_2,1)
    ELSEIF(('23'>qty_2 && qty_3<='23'),price_3,1)
    ELSEIF('23'>qty_3,price_4,1)
    END IF) as total 
 from product;

7
вам следует использовать CASE
сэр Руфо,

Ответы:


202

У вас есть то, что вы использовали в подобных хранимых процедурах для справки, но они не предназначены для использования так, как сейчас. Вы можете использовать, IFкак показано duskwuff. Но Caseзаявление лучше для глаз. Как это:

select id, 
    (
    CASE 
        WHEN qty_1 <= '23' THEN price
        WHEN '23' > qty_1 && qty_2 <= '23' THEN price_2
        WHEN '23' > qty_2 && qty_3 <= '23' THEN price_3
        WHEN '23' > qty_3 THEN price_4
        ELSE 1
    END) AS total
 from product;

Это выглядит чище. Я полагаю, вам все равно не нужно внутреннее SELECT..


2
Да, действительно, это выглядит лучше, я выберу этот вариант, но хорошо иметь оба подхода для будущих ссылок .. Спасибо, nawfal
Иван Браво Карлос

Приятно использовать CASE для IF. Спасибо, Науфал
Сатья Каллури

20

IF()в MySQL - это тернарная функция, а не структура управления - если условие в первом аргументе истинно, оно возвращает второй аргумент; в противном случае возвращается третий аргумент. Нет соответствующей ELSEIF()функции или END IFключевого слова.

Ближайший эквивалент того, что у вас есть, будет примерно таким:

IF(qty_1<='23', price,
  IF('23'>qty_1 && qty_2<='23', price_2,
    IF('23'>qty_2 && qty_3<='23', price_3,
      IF('23'>qty_3, price_4, 1)
    )
  )
)

Не все условия имеют для меня смысл (похоже, что некоторые из них могут быть случайно отменены?), Но, не зная, чего именно вы пытаетесь достичь, мне трудно это исправить.


Я понял это минуту назад ... выберите productoid, Precio, Precio_2, Precio_3, IF (cant_1> 23, Precio, IF (23> cant_1 && cant_2> 23, Precio_2, IF (23> cant_2 && cant_3> 23, Precio_3) , IF (23> cant_4, Precio_4,1)))) как итог по продукту, но дело в том, что я не могу создать отдельную таблицу цен из-за моего запроса босса, что было бы намного проще сделать соединение и получить цена в зависимости от количества ...
Иван Браво Карлос

было бы использовать более близкую вещьcase when (condition) then {computed value} when then else end
ahnbizcad

9

Я обнаружил ошибку в MySQL 5.1.72 при использовании вложенных функций if () .... значение переменных столбца (например, qty_1) пусто внутри второго if (), что делает его бесполезным. Вместо этого используйте следующую конструкцию:

case 
  when qty_1<='23' then price
  when '23'>qty_1 && qty_2<='23' then price_2
  when '23'>qty_2 && qty_3<='23' then price_3
  when '23'>qty_3 then price_4
  else 1
end

4

На ваш вопрос:

SELECT id, 
   IF(qty_1 <= '23', price,
   IF(('23' > qty_1 && qty_2 <= '23'), price_2,
   IF(('23' > qty_2 && qty_3 <= '23'), price_3,
   IF(('23' > qty_2 && qty_3<='23'), price_3,
   IF('23' > qty_3, price_4, 1))))) as total 
FROM product;

Вы можете использовать if - elseструктуру управления или IFфункцию в MySQL.

Ссылка:
http://easysolutionweb.com/sql-pl-sql/how-to-use-if-and-else-in-mysql/


1
Хотя ваш ответ на 100% правильный, он также может стать на 100% бесполезным, если эта ссылка будет перемещена, изменена, объединена с другой или основной сайт просто исчезнет ... :-( Поэтому, пожалуйста, отредактируйте свой ответ и скопируйте соответствующий переходите от ссылки к вашему ответу, тем самым гарантируя ваш ответ на 100% времени существования этого сайта! ;-) Вы всегда можете оставить ссылку внизу своего ответа в качестве источника для вашего материала ...
Дональд Дак

2

Согласно ответу Nawfal, операторы IF должны быть в процедуре. Я нашел этот пост, в котором показан блестящий пример использования вашего скрипта в процедуре, которая все еще разрабатывается и тестируется. По сути, вы создаете, вызываете, а затем отбрасываете процедуру:

https://gist.github.com/jeremyjarrell/6083251

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.