Использование предложения 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 разные столбцы для каждого объединения.