mysql извлекает максимальный интервал между событиями - PullRequest
0 голосов
/ 03 октября 2018

Когда у меня есть таблица, мне нужно получить максимальную разницу между событиями в запросе mysql, например,

time/event
1/a
2/a
5/a
7/a
1/b
4/b
15/b

, в этом случае ответ должен быть (15-4), следовательно, 11 / b

таблица не отсортирована, это было только для демонстрации моей проблемы

Ответы [ 3 ]

0 голосов
/ 03 октября 2018

Если у вас нет доступа к функции LEAD, вы можете присоединиться к таблице вместе с ней, чтобы найти следующую строку :

SELECT curr.time, curr.event, MIN(next.time) - curr.time AS diff
FROM testdata AS curr
INNER JOIN testdata AS next ON next.event = curr.event AND next.time > curr.time
GROUP BY curr.time, curr.event
ORDER BY diff DESC
LIMIT 1

Результат:

+------+-------+------+
| time | event | diff |
+------+-------+------+
|    4 | b     |   11 |
+------+-------+------+

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

+------+-------+------+
| time | event | diff |
+------+-------+------+
|    1 | a     |    1 |
|    2 | a     |    3 |
|    5 | a     |    2 |
|    1 | b     |    3 |
|    4 | b     |   11 |
+------+-------+------+
0 голосов
/ 03 октября 2018

Хотя предложение Гордона должно работать (назначение псевдонимов, совпадающих с именами таблиц, @Gordon?), Оно будет очень медленным (O (N ^ 2)).

CREATE FUNCTION maxgap()
RETURNS VARCHAR(30)
READS SQL DATA
BEGIN
   DECLARE prevtime INT;
   DECLARE prevevent VARCHAR(20) DEFAULT '';
   DECLARE curtime INT;
   DECLARE curevent VARCHAR(20);
   DECLARE maxtime INT;
   DECLARE maxevent VARCHAR(20);
   DECLARE finished INTEGER DEFAULT 0;

   DECLARE curs CURSOR FOR
      SELECT UNIX_TIMESTAMP(time), event FROM yourtable ORDER BY event,time;
   DECLARE CONTINUE HANDLER 
      FOR NOT FOUND SET finished = 1;

   get_records: LOOP
      FETCH curs INTO curtime, curevent;
      IF finished = 1 THEN 
           LEAVE get_records;
      END IF;
      IF (curevent != prevevent) THEN
         SET prevtime=curtime;
         SET prevevent=curevent;
      END IF 
      IF (maxtime<curtime-prevtime) THEN
         SET maxtime=curtime-prevtime;
         SET maxevent=curevent;
      END IF
    END LOOP get_records;
    CLOSE curs;

    RETURN (CONCAT(maxtime, '/', maxevent));

  END$$

(оно должноможно создать такое же поведение, используя переменные в выбранной группе, но от одной мысли об этом у меня болит голова).

0 голосов
/ 03 октября 2018

Вам нужен предыдущий или следующий раз для события.Я бы предложил подзапрос:

select t.*
from (select t.*,
             (select t2.time
              from t t2
              where t2.event = t.event and t2.time < t.time
              order by t2.time desc
              limit 1
             ) as prev_time
      from t
     ) t
where prev_time is not null
order by (time - prev_time) desc
limit 1;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...