У меня есть следующая таблица в качестве примера:

numbers    type
--------------
1          1
5          2
6          1
8          2
9          3
14         2 
3          1

Из этой таблицы я хотел бы выбрать ближайшее число, которое меньше или равно 5 И типа 1, и если такого соответствия строк нет, то (и только тогда) я хотел бы вернуть первое ближайшее число, большее 5 из тип 2

Я могу решить эту проблему, выполнив два запроса:

SELECT number FROM numbers WHERE number <= 5 AND type = 1 ORDER BY number LIMIT 1

И если приведенный выше запрос возвращает 0 результатов, я просто запускаю второй запрос:

SELECT number FROM numbers WHERE number > 5 AND type = 2 ORDER BY number LIMIT 1

Но возможно ли достичь того же результата, используя только один запрос?

Я думал что-то вроде

SELECT number FROM numbers WHERE (number <= 5 AND type = 1) OR (number > 5 AND type = 2) ORDER BY number LIMIT 1

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

0
Askerman 28 Фев 2019 в 11:01

2 ответа

Лучший ответ

Этот запрос сделает то, что вы хотите. Он выбирает все числа, которые соответствуют вашим двум ограничениям запроса, и упорядочивает результаты сначала по type (так что, если есть результат для типа 1, он появится первым), а затем по -number или number в зависимости от type (так что числа <= 5 сортируются в порядке убывания, а числа> 5 сортируются в порядке возрастания):

SELECT number 
FROM numbers
WHERE ( number <= 5 AND type = 1 )
   OR ( number > 5 AND type = 2 )
ORDER BY type, CASE WHEN type = 1 THEN -number ELSE number END
LIMIT 1

Выход:

3

Демо на dbfiddle

2
Strawberry 28 Фев 2019 в 08:28

Объедините два, и вы всегда предпочитаете тип 1, а не тип 2, следовательно, ORDER BY и LIMIT. ABS означает, что будет первым по типу, это число, близкое к числу 5.

SELECT number, type
FROM numbers
WHERE (number <=5 AND type=1) OR
      (number > 5 AND type=2)
ORDER BY type ASC, ABS(number-5) ASC
LIMIT 1
0
danblack 28 Фев 2019 в 08:22