mysql ORDER BY CASE не возвращает ожидаемые результаты - PullRequest
0 голосов
/ 24 сентября 2019

У меня есть следующий запрос с ORDER BY CASE, который не возвращает ожидаемые результаты

SELECT 
c.* 
  FROM `ws_products` as c 
ORDER BY 
CASE WHEN c.stock>=0 THEN 1 
   WHEN (c.stock<=0 AND c.allow_backorder=1) THEN 2 
   WHEN (c.stock<=0 AND c.allow_backorder=0) THEN 3 END asc

Я хочу отсортировать товары в следующем порядке

  • Сначала продукты, которые имеютstock (c.stock> = 0)
  • Во-вторых, у товаров, у которых нет запаса, но разрешен allow_backorder (c.stock <= 0 AND c.allow_backorder = 1) </li>
  • Последние товары, которыене имеет запасов и не имеет разрешения allow_backorder (c.stock <= 0 AND c.allow_backorder = 0) </li>

Я ожидал, что вышеуказанный запрос выполнит свою работу, но это не

Я неправильно понял СЛУЧАЙ КОГДА MySQL?

Мой подход совершенно неверен?

Любая помощь приветствуется

Ответы [ 2 ]

2 голосов
/ 24 сентября 2019

@ Мадхур правильно прыгнул на проблему с его комментарием, но в дополнение к тому, что он сказал, вы можете упростить выражение CASE немного больше:

SELECT c.*
FROM ws_products AS c
ORDER BY 
CASE WHEN c.stock > 0 THEN 1
     WHEN c.allow_backorder = 1 THEN 2
     ELSE 3 END;

Это работает, потому что если запас не больше нуля, то по определению оно должно быть равно нулю или меньше, поэтому нам не нужно явно проверять это в последующих случаях.Я предполагаю, что мы можем просто поместить allow_backorder = 0 в условие ELSE, предполагая, что 0 и 1 являются единственно возможными значениями (а если нет, то ваше исходное выражение CASE должно было иметь свое собственное условие ELSE).

0 голосов
/ 24 сентября 2019

Альтернатива для этого:

ORDER BY 
CASE WHEN c.stock>0 THEN 1 
  WHEN (c.stock<=0 AND c.allow_backorder=1) THEN 2 
  WHEN (c.stock<=0 AND c.allow_backorder=0) THEN 3 END asc

Мне больше нравится этот формат (список условий):

ORDER BY
  c.stock>0 DESC,
  c.stock<=0 AND c.allow_backorder=1 DESC,
  c.stock<=0 AND c.allow_backorder=0 DESC

И теперь мы можем оптимизировать его (используется только условие c.stock>=0)один раз, при условии, что c.allow_backorder имеет значение 0 или 1)

ORDER BY c.stock <= 0, c.allow_backorder DESC
...