Выяснение UIDS из большого набора данных MySQL, где данные не изменились 'n' раз - PullRequest
0 голосов
/ 12 мая 2019

У меня есть следующая таблица.

id(Primary) uid   data      Time
1           1       20      2019-05-12 10:17:26
2           2       23      2019-05-12 10:17:26
3           3       45      2019-05-12 10:17:26
4           4       16      2019-05-12 10:17:26
5           2       23      2019-05-12 10:18:26
6           1       26      2019-05-12 10:18:26
7           4       15      2019-05-12 10:18:26
8           3       41      2019-05-12 10:18:26
9           4       15      2019-05-12 10:19:26
10          2       23      2019-05-12 10:19:26
11          3       38      2019-05-12 10:19:26
12          1       31      2019-05-12 10:19:26
13          3       48      2019-05-12 10:20:26
14          4       15      2019-05-12 10:20:26
15          1       19      2019-05-12 10:20:26
16          2       23      2019-05-12 10:20:26
17          1       22      2019-05-12 10:21:26
18          4       15      2019-05-12 10:21:26
19          2       23      2019-05-12 10:21:26
20          3       43      2019-05-12 10:21:26

Я хочу узнать уникальные идентификаторы UID, в которых самые последние n записей были одинаковыми.В приведенных выше данных, когда n = 5, мне нужно 2 в качестве результата.когда n = 4, мне нужно 2 и 4 в наборе результатов.

1 Ответ

1 голос
/ 13 мая 2019

Прямой подход использует 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, чтобы получить счет.

дб <> скрипка

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...