Можно ли вывести результат объединения двух подзапросов в чередующемся порядке? - PullRequest
4 голосов
/ 21 февраля 2020

Допустим, у меня есть два подзапроса в операторе UNION, например, так:

(
    SELECT * 
    FROM users
    ORDER BY registration_date
) 
UNION ALL
(
    SELECT *
    FROM food
    ORDER BY popularity
)

Вывод следующий:

Bob
Alice
Steve
Mark
...
Sandwich
Pizza
Burger
Fries
...

Можно ли выводить их поочередно , такой, что вывод:

Bob
Sandwich
Alice
Pizza
Steve
Burger
Mark
Fries
...

Каждый вывод запроса состоит из тысяч элементов.

Ответы [ 3 ]

1 голос
/ 21 февраля 2020

На всякий случай, если вы не используете MySQL 8+, вы все равно можете смоделировать ROW_NUMBER с помощью коррелированного запроса подсчета:

(
    SELECT 1 AS idx, name,
        (SELECT COUNT(*) FROM users u2 WHERE u2.registration_date < u1.registration_date) rn
    FROM users u1
)
UNION ALL
(
    SELECT 2, name,
        (SELECT COUNT(*) FROM food f2 WHERE f2.popularity < f1.popularity) rn
    FROM food f1
)
ORDER BY
    rn,
    idx;
1 голос
/ 21 февраля 2020

Вы можете использовать row_number(), если вы используете MySQL 8.0:

(select name, 1 src, row_number() over(order by registration_date) rn from users)
union all 
(select name, 2, row_number() over(order by popularity) from food)
order by rn, src

В каждом union ed подзапросе мы используем row_number() для ранжирования записей и добавления еще одного столбца, вызывается src, чтобы определить, из какой таблицы поступает запись.

Затем остается только order by назначенный row_number(), используя дополнительный столбец для чередования записей.

Обратите внимание, что я изменил ваш запрос, чтобы перечислить столбцы select ed в подзапросах; select * обычно не является хорошей практикой, особенно с union all, который требует, чтобы оба набора данных имели одинаковое количество столбцов (с эквивалентными типами данных).

0 голосов
/ 21 февраля 2020

ОБЪЯВИТЬ @id INT; SET @id: = 0;

SELECT id, t. * FROM (SELECT u. *, (@ id:=@id+1) AS id

ОТ пользователей u ЗАКАЗАТЬ по дате регистрации) СОЮЗ ВСЕХ ( ВЫБЕРИТЕ f. *, (@ id:=@id+2) AS id

FROM food f 
ORDER BY popularity

) t ЗАКАЗАТЬ ПО ID;

...