Использование предложения union и order by в mysql
Я хочу использовать порядок с помощью union в запросе mysql.
Я извлекаю разные типы записей на основе разных критериев из таблицы, основанной на расстоянии для поиска на моем сайте.
Первый запрос выбора возвращает данные, связанные с точным поиском места.
Второй запрос выбора возвращает данные, относящиеся к расстоянию в пределах 5 км от места поиска.
Третий запрос выбора возвращает данные, связанные с расстоянием в пределах 5-15 км от места поиска.
Затем я m с помощью объединения объединяет все результаты и показывается на странице с пейджингом. Под соответствующим заголовком "Точные результаты поиска" , "Результаты в пределах 5 км" и т.д.
Теперь я хочу сортировать результаты на основе id или add_date. Но когда я добавляю order by clause в конце моего запроса (query1 union query 2 union query 3 order by add_date). Он сортирует все результаты. Но я хочу, чтобы он сортировался под каждым заголовком.
Ответы
Ответ 1
Вы можете сделать это, добавив псевдо-столбец с именем rank к каждому элементу, который вы можете сортировать сначала, прежде чем сортировать по другим критериям, например:
select *
from (
select 1 as Rank, id, add_date from Table
union all
select 2 as Rank, id, add_date from Table where distance < 5
union all
select 3 as Rank, id, add_date from Table where distance between 5 and 15
) a
order by rank, id, add_date desc
Ответ 2
Для этого вы можете использовать подзапросы:
select * from (select values1 from table1 order by orderby1) as a
union all
select * from (select values2 from table2 order by orderby2) as b
Ответ 3
(select add_date,col2 from table_name)
union
(select add_date,col2 from table_name)
union
(select add_date,col2 from table_name)
order by add_date
Ответ 4
Запрос объединения может содержать только одно главное предложение ORDER BY
, IIRC. Чтобы получить это, в каждом запросе, составляющем более высокий запрос UNION
, добавьте поле, которое будет единственным полем, которое вы сортируете для UNION
ORDER BY
.
Например, у вас может быть что-то вроде
SELECT field1, field2, '1' AS union_sort
UNION SELECT field1, field2, '2' AS union_sort
UNION SELECT field1, field2, '3' AS union_sort
ORDER BY union_sort
Это поле union_sort
может быть любым, что вы можете отсортировать. В этом примере просто случается, что сначала выводятся первые таблицы, вторая вторая и т.д.
Ответ 5
Не забывайте, что объединение всех - это способ добавления записей в набор записей без сортировки или слияния (в отличие от объединения).
Итак, например:
select * from (
select col1, col2
from table a
<....>
order by col3
limit by 200
) a
union all
select * from (
select cola, colb
from table b
<....>
order by colb
limit by 300
) b
Сохраняет отдельные запросы более четко и позволяет сортировать по различным параметрам в каждом запросе. Однако, используя выбранный способ ответа, он может стать более ясным в зависимости от сложности и того, как связаны данные, потому что вы концептуализируете сортировку. Он также позволяет вам вернуть искусственный столбец в программу запросов, чтобы он имел контекст, который он может сортировать или организовывать.
Но этот способ имеет преимущество: быть быстрым, не вводить дополнительные переменные и упрощать разделение каждого запроса, включая сортировку. Возможность добавления лимита - это просто дополнительный бонус.
И, конечно, не стесняйтесь превращать союз в объединение и добавлять сортировку для всего запроса. Или добавьте искусственный идентификатор, и в этом случае этот способ упрощает сортировку по различным параметрам в каждом запросе, но в остальном он совпадает с принятым ответом.
Ответ 6
Я работал над объединением и объединением.
(SELECT
table1.column1,
table1.column2,
foo1.column4
FROM table1, table2, foo1, table5
WHERE table5.somerecord = table1.column1
ORDER BY table1.column1 ASC, table1.column2 DESC
)
UNION
(SELECT
... Another complex query as above
)
ORDER BY column1 DESC, column2 ASC
Ответ 7
Try:
SELECT result.*
FROM (
[QUERY 1]
UNION
[QUERY 2]
) result
ORDER BY result.id
Где [QUERY 1] и [QUERY 2] - ваши два запроса, которые вы хотите объединить.
Ответ 8
Это потому, что вы сортируете весь набор результатов, вы должны сортировать, каждую часть объединения отдельно или вы можете использовать ORDER BY (что-то, то есть интервал подзапроса). Предложение THEN (что-то, т.е. строка id)
Ответ 9
Я попытался добавить порядок к каждому из запросов до объединения, например
(select * from table where distance=0 order by add_date)
union
(select * from table where distance>0 and distance<=5 order by add_date)
но он, похоже, не работал. Это фактически не упорядочивало строки из каждого выбора.
Я думаю, вам нужно будет сохранить порядок снаружи и добавить столбцы в предложение where к порядку, что-то вроде
(select * from table where distance=0)
union
(select * from table where distance>0 and distance<=5)
order by distance, add_date
Это может быть немного сложно, поскольку вы хотите группировать диапазоны, но я думаю, что это должно быть выполнимо.
Ответ 10
Когда вы используете предложение ORDER BY
внутри подзапроса, используемого вместе с UNION
mysql оптимизирует предложение ORDER BY
.
Это потому, что по умолчанию 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
разные столбцы для каждого объединения.