объединение двух запросов mysql с порядком по

#mysql

#mysql

Вопрос:

Я хочу объединить два запроса, которые имеют разные ORDER BY

однако другой запрос не ведет себя в соответствии с его ORDER BY

Я не знаю, что вызывает эту ошибку, но она отлично работает в моих локальных файлах. но когда я запускаю его на реальном сайте, поведение второго запроса не работает должным образом.

проблема заключалась в том, что sub-query table2 он должен отображать все записи по порядку starting_date descending , но запрос не сортируется таким образом… Я не знаю, что является причиной этого.

заранее спасибо

вот мой запрос mysql.

  SELECT * FROM (
            SELECT 
            events.event_id,
            events.event_name_en,
            events.event_name_ch,
            events.event_description_en,
            events.event_description_ch,
            events.ref,
            events.start_date,
            events.end_date,
            events.venue_id,
            events.organizers_id,
            events.website,
            events.payment_method,
            events.visitors,
            events.display,
            events.booking_form,
            events.map,
            events.lmap,
            events.insurance_offered,
            events.masterhead_img,
            events.icon_img,
            events.event_token,
            events.added_by as event_added_by,
            events.added_date as event_added_date,
            events.updated_by,
            events.updated_date,
            events.active,
            events.allow_ond,
            events.allow_ond_reg,
            events.terms_p,
            events.cancel_p,
            events.no_show_p,
            events.refund_p,
            events.official_desc,
            events.supporting_desc,
            events.participating_desc,
            events.official_title,
            events.supporting_title,
            events.participating_title,
            events.order_number,
            venue.venue_en,
            venue.venue_ch,
            venue.added_by as venue_added_by,
            venue.added_date as venue_added_date,
            venue.updated_by as venue_updated_by,
            venue.updated_date as venue_updated_date,
            countries.country_id,
            countries.country_code,
            countries.country_name

            FROM 
            events 
            INNER JOIN venue
            ON venue.venue_id=events.venue_id
            INNER JOIN countries
            ON countries.country_id=events.country_id
            WHERE events.display = '1' AND events.order_number != ''
            AND events.active = '1' 
            ORDER BY events.order_number ASC) as table1

            UNION ALL

            SELECT * FROM (SELECT 
            events.event_id,
            events.event_name_en,
            events.event_name_ch,
            events.event_description_en,
            events.event_description_ch,
            events.ref,
            events.start_date,
            events.end_date,
            events.venue_id,
            events.organizers_id,
            events.website,
            events.payment_method,
            events.visitors,
            events.display,
            events.booking_form,
            events.map,
            events.lmap,
            events.insurance_offered,
            events.masterhead_img,
            events.icon_img,
            events.event_token,
            events.added_by as event_added_by,
            events.added_date as event_added_date,
            events.updated_by,
            events.updated_date,
            events.active,
            events.allow_ond,
            events.allow_ond_reg,
            events.terms_p,
            events.cancel_p,
            events.no_show_p,
            events.refund_p,
            events.official_desc,
            events.supporting_desc,
            events.participating_desc,
            events.official_title,
            events.supporting_title,
            events.participating_title,
            events.order_number,
            venue.venue_en,
            venue.venue_ch,
            venue.added_by as venue_added_by,
            venue.added_date as venue_added_date,
            venue.updated_by as venue_updated_by,
            venue.updated_date as venue_updated_date,
            countries.country_id,
            countries.country_code,
            countries.country_name

            FROM 
            events 
            INNER JOIN venue
            ON venue.venue_id=events.venue_id
            INNER JOIN countries
            ON countries.country_id=events.country_id
            WHERE events.display = '1' AND events.order_number = ''
            AND events.active = '1' 
            ORDER BY events.start_date DESC) as table2
  

Результат:

первые две строки хороши. результат table1 sub-query

но когда вы смотрите на третью строку и так далее .. порядок starting_date desc не работает должным образом… третья строка должна быть world engineer blah.....

введите описание изображения здесь

Комментарии:

1. UNION Это не «вот два запроса, объедините их строки». Объединение проверяет и отбрасывает повторяющиеся строки. Таким образом, UNION не гарантируется сохранение порядка объединенных подзапросов. Лучший способ сделать это — SELECT и дополнительный, синтезированный столбец из обоих подзапросов таким образом, чтобы, когда внешний запрос выполняется по порядку, конечным результатом был ваш общий желаемый порядок сортировки.

2. привет @SamVarshavchik но я использую UNION ALL , он не должен отбрасывать повторяющиеся строки. можете ли вы помочь мне составить запрос для этого, сэр? я действительно не очень хорош, когда дело доходит до этого.

3. Ваши предполагаемые условия сортировки не имеют смысла. Вы хотите отсортировать первый подзапрос по возрастанию номера заказа, а второй по убыванию по дате начала события. Можете ли вы пояснить, что вы здесь имеете в виду?

4. Как вы предлагаете сравнивать номер заказа, предположительно целое число, с датой?

5. @TimBiegeleisen, потому что сортировка по умолчанию для этого — starting_date по убыванию… но мой клиент хочет, чтобы, если он может манипулировать сортировкой с помощью ручного вмешательства,,, поэтому, если он сначала установит приоритет для отображения некоторых событий, он сможет .. и после этого остальные события, у которых нет order_number, будут отсортированы по убыванию starting_date

Ответ №1:

Со страниц руководства по MySQL

http://dev.mysql.com/doc/refman/5.7/en/union.html

Однако, использование ORDER BY для отдельных операторов SELECT ничего не говорит о порядке, в котором строки отображаются в конечном результате, поскольку ОБЪЕДИНЕНИЕ по умолчанию создает неупорядоченный набор строк. Следовательно, использование ORDER BY в этом контексте обычно используется в сочетании с LIMIT , так что оно используется для определения подмножества выбранных строк для извлечения при ВЫБОРЕ, даже если это не обязательно влияет на порядок этих строк в конечном результате ОБЪЕДИНЕНИЯ. Если ORDER BY отображается в SELECT без ОГРАНИЧЕНИЙ, он оптимизируется, потому что в любом случае это не будет иметь никакого эффекта.

Я думаю, вы могли бы сделать то, что хотите, поиграв с предложением ORDER BY:-

 SELECT events.event_id,
        events.event_name_en,
        events.event_name_ch,
        events.event_description_en,
        events.event_description_ch,
        events.ref,
        events.start_date,
        events.end_date,
        events.venue_id,
        events.organizers_id,
        events.website,
        events.payment_method,
        events.visitors,
        events.display,
        events.booking_form,
        events.map,
        events.lmap,
        events.insurance_offered,
        events.masterhead_img,
        events.icon_img,
        events.event_token,
        events.added_by as event_added_by,
        events.added_date as event_added_date,
        events.updated_by,
        events.updated_date,
        events.active,
        events.allow_ond,
        events.allow_ond_reg,
        events.terms_p,
        events.cancel_p,
        events.no_show_p,
        events.refund_p,
        events.official_desc,
        events.supporting_desc,
        events.participating_desc,
        events.official_title,
        events.supporting_title,
        events.participating_title,
        events.order_number,
        venue.venue_en,
        venue.venue_ch,
        venue.added_by as venue_added_by,
        venue.added_date as venue_added_date,
        venue.updated_by as venue_updated_by,
        venue.updated_date as venue_updated_date,
        countries.country_id,
        countries.country_code,
        countries.country_name
FROM events 
INNER JOIN venue ON venue.venue_id = events.venue_id
INNER JOIN countries ON countries.country_id = events.country_id
WHERE events.display = '1' 
AND events.active = '1' 
ORDER BY IF(events.order_number = '', 1, 0),
        IF(events.order_number = '', NULL, events.order_number) ASC,
        IF(events.order_number = '', events.start_date, NULL) DESC
  

Это упорядочит сначала все записи, которые поступили бы из вашего первого подзапроса, а затем все записи из 2-го подзапроса. В рамках этого он упорядочит первый по order_number по возрастанию, а 2-й по start_date по убыванию.