Прямой подход использует ALL
и подзапрос, получая последние n (пусть теперь n = 5) записи с использованием ORDER BY
и LIMIT
.
SELECT *
FROM (SELECT DISTINCT
t1.uid
FROM elbat t1) x
WHERE (SELECT t2.data
FROM elbat t2
WHERE t2.uid = t1.uid
ORDER BY time DESC
LIMIT 1) = ALL (SELECT t3.data
FROM elbat t3
WHERE t3.uid = t1.uid
ORDER BY time DESC,
id DESC
LIMIT 5);
К сожалению, MySQL не разрешает ограничение в подзапросах до ALL
.
В MySQL 8 мы можем исправить это, добавив еще один подзапрос в подзапрос, в котором мы используем LIMIT
.
SELECT *
FROM (SELECT DISTINCT
t1.uid
FROM elbat t1) x
WHERE (SELECT t2.data
FROM elbat t2
WHERE t2.uid = x.uid
ORDER BY time DESC
LIMIT 1) = ALL (SELECT x.data
FROM (SELECT t3.data
FROM elbat t3
WHERE t3.uid = x.uid
ORDER BY time DESC,
id DESC
LIMIT 5) x);
Опять же, к сожалению, это не сработает в версиях ниже 8, поскольку на значения из внешнего запроса нельзя ссылаться более чем на один уровень, поэтому x.uid
неизвестен в самом внутреннем подзапросе.
Но мы можем проверить число следующих строк, которые мы получаем в другом подзапросе, чтобы оно было меньше 5 ( n ).
SELECT *
FROM (SELECT DISTINCT
t1.uid
FROM elbat t1) x
WHERE (SELECT t2.data
FROM elbat t2
WHERE t2.uid = x.uid
ORDER BY time DESC
LIMIT 1) = ALL (SELECT t3.data
FROM elbat t3
WHERE t3.uid = x.uid
AND (SELECT count(*)
FROM elbat t4
WHERE t4.uid = t3.uid
AND (t4.time > t3.time
OR t4.time = t3.time
AND t4.id > t3.id)) < 5);
Обратите внимание, что это также вернет результаты для uid
, где имеется менее 5 ( n ) строк, но все с равными data
. Если в таком случае вы хотите исключить соответствующий uid
, вам нужно добавить еще один подзапрос, получающий счетчик последней строки для uid
, и проверить, больше или равен 5 ( n ). ). Просто возьмите один из подзапросов ALL
и дайте ему вернуть count(*)
вместо t3.data
, чтобы получить счет.
дб <> скрипка