Когда вы используете ORDER BY
предложение внутри подзапроса, используемого вместе с UNION
mysql, оптимизирует ORDER BY
предложение.
Это связано с тем, что по умолчанию a UNION
возвращает неупорядоченный список, поэтому ORDER BY
он ничего не сделает.
Оптимизация упоминается в документации и говорит:
Чтобы применить ORDER BY или LIMIT к отдельному SELECT, поместите предложение в круглые скобки, которые заключают SELECT:
(SELECT a FROM t1 WHERE a=10 AND B=1 ORDER BY a LIMIT 10) UNION
(SELECT a FROM t2 WHERE a=11 AND B=2 ORDER BY a LIMIT 10);
Однако использование ORDER BY для отдельных операторов SELECT ничего не говорит о порядке, в котором строки появляются в окончательном результате, поскольку UNION по умолчанию создает неупорядоченный набор строк. Таким образом, использование ORDER BY в этом контексте обычно связано с LIMIT, так что он используется для определения подмножества выбранных строк для извлечения для SELECT, даже если это не обязательно влияет на порядок этих строк в окончательный результат UNION. Если ORDER BY появляется без LIMIT в SELECT, он оптимизируется, потому что в любом случае это не будет иметь никакого эффекта.
Последнее предложение немного вводит в заблуждение, потому что оно должно иметь эффект. Эта оптимизация вызывает проблему, когда вы находитесь в ситуации, когда вам нужно сделать заказ в подзапросе.
Чтобы заставить MySQL не выполнять эту оптимизацию, вы можете добавить предложение LIMIT, например:
(SELECT 1 AS rank, id, add_date FROM my_table WHERE distance < 5 ORDER BY add_date LIMIT 9999999999)
UNION ALL
(SELECT 2 AS rank, id, add_date FROM my_table WHERE distance BETWEEN 5 AND 15 ORDER BY rank LIMIT 9999999999)
UNION ALL
(SELECT 3 AS rank, id, add_date from my_table WHERE distance BETWEEN 5 and 15 ORDER BY id LIMIT 9999999999)
Высокое LIMIT
означает, что вы можете добавить OFFSET
к общему запросу, если хотите сделать что-то вроде разбивки на страницы.
Это также дает вам дополнительное преимущество - возможность использовать ORDER BY
разные столбцы для каждого объединения.