Для решения этого вопроса можно применить два способа, которые условно можно назвать дифференциальным и интегральным.
Первый способ, дифференциальный, основан на определении для каждой строки, подходит ли она. Для этого требуются номера строк, получить которые можно с помощью оконных функций.
SELECT *
FROM (SELECT *,
ROW_NUMBER() OVER (ORDER BY id DESC) AS RowNum
FROM messages
WHERE dialog_id=3
) AS _
WHERE RowNum<=50 OR read_status=false
ORDER BY id DESC;
Другой способ, интегральный, оперирует совокупностями записей, что более соответствует духу SQL.
(SELECT * FROM messages WHERE dialog_id=3 ORDER BY id DESC LIMIT 50)
UNION
SELECT * FROM messages WHERE dialog_id=3 AND read_status=false
ORDER BY id DESC;
Обращаю внимание, что использовать надо именно UNION, а не UNION ALL, чтобы исключить дубликаты.
Пример приведу ненастоящий, простой, только для наглядности.
Таблица `messages` с полями `id`, `dialog_id`, `author_id`, `content`, `read_status`.
Допустим мы хотим сделать выборку всех сообщений where `dialog_id`=3, выборку сортируем ORDER BY `id` DESC ну и ставим лимит LIMIT 50
Но если нам нужно получить больше сообщений когда кол-во непрочитанных (`read_status`=false) за границами лимита.
Конечно можно сделать предварительный запрос, можно подзапрос. Но может я что-то упускаю.
Есть ли какой-то функционал в mysql что бы остановить выборку при соответствии дополнительного условия?