SQL-запрос, чтобы получить разницу между соседними записями - PullRequest
4 голосов
/ 03 марта 2011

У меня проблемы с чем-то, что я хочу получить из таблицы базы данных.

Таблица выглядит так

startTime  endTime type
1:00       1:02    A    
1:20       1:30    A
3:45       3:50    A
1:30       1:40    B
2:30       2:31    A
3:00       3:01    A
...

Я хочу получить средний промежуток времени (время начала следующего действия A минус время его начала) для каждого типа действия.

Как мне это сделать?

Edit:

Есть правило. Если интервал больше 1 часа, он не считается в среднем. Поэтому он не равен всему временному интервалу, деленному на количество интервалов. Так и становится, (только для А)

startTime  endTime type
1:00       1:02    A    
1:20       1:30    A
2:30       2:31    A
3:00       3:01    A
3:45       3:50    A

Расчет должен быть 1:20 - 1:00 = 20 минут (возьмите эту запись) 2:30 - 1:20 = 70 мин (отменить эту запись) 3:00 - 2:30 = 30 минут (примите это) 3:45 - 3:00 = 45 минут (примите это)

Окончательный результат должен быть (20 + 30 + 45) / 3

Ответы [ 2 ]

3 голосов
/ 03 марта 2011

Я думаю, что нельзя избежать небольшого переформатирования данных, и для этого вы можете использовать временную таблицу.

Примечание : я создал таблицу с целыми числами вместо времени в качестве исходных данных, чтобы избежать всех вычислений формата времени, но на самом деле это то же самое.

Исходные данные, которые я создал:

CREATE TABLE `table` (
`start` INT(11) NOT NULL,
`end` INT(11) NOT NULL,
`type` VARCHAR(6));

INSERT INTO `table` VALUES
(1,3,'A'),
(5,7,'A'),
(6,10,'A'),
(2,6,'B'),
(3,4,'B'),
(5,11,'B'),
(12,13,'B');

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

DROP TABLE IF EXISTS temp;
CREATE TABLE temp (
id int(100) AUTO_INCREMENT,
start int(11) NOT NULL,
type VARCHAR(6),
PRIMARY KEY id (id));

INSERT INTO temp(start, type) 
SELECT start, type FROM table
ORDER BY type, start;

SELECT t1.type, AVG(t1.start - t2.start) AS avg_gap 
FROM temp t1
JOIN temp t2 ON t1.type = t2.type AND t1.id = (t2.id + 1)
WHERE t1.start - t2.start < 5
GROUP BY t1.type;

И результат:

type   avg_gap
 A     2.5
 B     1.5

РЕДАКТИРОВАТЬ: В соответствии с вашим новым правилом в редактировании: мое правило - не вычислять разрывы больше 5 (как вы можете видеть в предложении WHERE окончательного запроса). Следовательно, последний пробел типа B. был проигнорирован.

0 голосов
/ 03 марта 2011

Хорошо, даже если проблема не такая, как в MySQL: средний интервал между записями к вам применимы другие действительные решения, например:

SELECT type, AVG(minutes)
FROM
(SELECT type, EXTRACT(MINUTE FROM TIMEDIFF(t2.startTime, MAX(t1.startTime))) minutes
FROM table t1 JOIN
     table t2 ON t1.type = t2.type AND 
                 t1.startTime > SUBTIME(t2.startTime, '01:00:00') AND 
                 t1.startTime < t2.startTime
GROUP BY type, t2.startTime
) x
GROUP BY type

В приведенном выше запросе есть несколько предположений:

  • тип startTime - ВРЕМЯ
  • уникален для каждого типа (два события не начинаются одновременно)
  • это фактически исключает любой интервал ровно один час, тоже
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...