Многоэлементный запрос возвращает меньше строк, чем ожидалось - PullRequest
0 голосов
/ 10 июня 2018

Я пытаюсь выбрать 5 «самых новых» строк (те, которые имеют самый высокий идентификатор), а затем 10 случайных строк, которые не должны быть ни одной из 5 самых новых.

(SELECT t1.img_app_id 
 FROM imgs_app t1 
 ORDER BY t1.img_app_id DESC 
 LIMIT 5)
UNION
(SELECT t2.img_app_id 
 FROM imgs_app t2 
 ORDER BY RAND() DESC 
 LIMIT 10 OFFSET 5)

Но по какой-то причинепоследний запрос возвращает только 7 строк?база данных в настоящее время имеет в общей сложности 29 строк.

Когда я заказываю DESC, я должен сначала получить самые высокие идентификаторы, а когда я использую смещение 5, я не должен получать ни одну из 5 новейших строк, верно?

Что я делаю не так в этом SQL?

Ответы [ 2 ]

0 голосов
/ 10 июня 2018

Обратите внимание, что ORDER BY RAND() DESC LIMIT 10 OFFSET 5 эквивалентно ORDER BY RAND() DESC LIMIT 5 OFFSET 0, что является ничем иным, как "5 случайными строками".Вы также можете просто написать ORDER BY RAND() LIMIT 10.

Так что для вашей второй части вам нужно будет либо «удалить» первые 5 строк в другом подзапросе, прежде чем «перетасовать» строки:

SELECT img_app_id 
FROM (
    SELECT img_app_id 
    FROM imgs_app
    ORDER BY img_app_id DESC 
    LIMIT 9999999999 OFFSET 5
) sub
ORDER BY RAND()
LIMIT 10

Другой способ (и, вероятно, более быстрый) - использовать подзапрос в предложении WHERE для «удаления» первых 5 строк:

SELECT img_app_id 
FROM imgs_app
WHERE img_app_id <= (
    SELECT img_app_id
    FROM imgs_app
    ORDER BY img_app_id DESC
    LIMIT 1 OFFSET 5
)
ORDER BY RAND()
LIMIT 10

Теперь вы можете использовать UNION [DISTINCT] или UNION ALL.Результат будет таким же, так как не может быть дубликатов.Но UNION ALL позволит избежать ненужной сортировки.

Окончательный запрос будет выглядеть так:

(
    SELECT t1.img_app_id 
    FROM imgs_app t1 
    ORDER BY t1.img_app_id DESC 
    LIMIT 5
) UNION ALL (
    SELECT img_app_id 
    FROM imgs_app
    WHERE img_app_id <= (
        SELECT img_app_id
        FROM imgs_app
        ORDER BY img_app_id DESC
        LIMIT 1 OFFSET 5
    )
    ORDER BY RAND()
    LIMIT 10
)

Обратите внимание, что UNION ALL allone не является решением.Вы просто получите несколько случайных дубликатов.

0 голосов
/ 10 июня 2018

UNION выполняет поэтапное объединение двух операций SELECT в вашем запросе.Если ваш последний запрос из пяти возвращает те же значения id, что и ваш случайный запрос, UNION подавляет дубликаты.

Попробуйте UNION ALL.

...