2014-09-26 1 views
1

У меня есть запрос MySQL, если другой пользователь в другом потоке, который производит список результатов времени ANPR на день пути в следующем формате:Min, Max, Средний и графы сгруппированы в 15-минутных бункера

Plate Date  Starttime Endtime Journey Time 
YF10PXE 2014-06-18 10:00:32 10:03:22 00:02:50 
KG55GOA 2014-06-18 10:00:39 10:03:25 00:02:46 
N380LGN 2014-06-18 10:00:43 10:03:44 00:03:01 
X557EFB 2014-06-18 10:01:05 10:03:31 00:02:26 
AJ61AOS 2014-06-18 10:01:32 10:41:09 00:39:37 
BG58ASO 2014-06-18 10:01:42 10:06:09 00:04:27 
HT56ENL 2014-06-18 10:02:21 10:07:27 00:05:06 
X449LGS 2014-06-18 10:02:51 11:51:42 01:48:51 
KR07DWW 2014-06-18 10:03:19 11:05:45 01:02:26 
NA59FKE 2014-06-18 10:03:35 10:44:17 00:40:42 
HV13MXY 2014-06-18 10:03:54 10:52:12 00:48:18 
HS03FUW 2014-06-18 10:04:35 10:06:19 00:01:44 
HX53FKP 2014-06-18 10:06:09 10:06:47 00:00:38 
HK11NJU 2014-06-18 10:07:25 10:08:06 00:00:41 
HN12OAV 2014-06-18 10:07:56 10:08:51 00:00:55 
MM08AZB 2014-06-18 10:08:10 10:08:53 00:00:43 
BW57ENK 2014-06-18 10:08:35 10:09:19 00:00:44 
AE55LHR 2014-06-18 10:08:35 10:09:18 00:00:43 
RV03HMA 2014-06-18 10:09:13 11:07:45 00:58:32 
JPO6JEM 2014-06-18 10:10:48 10:11:25 00:00:37 
BV62WMP 2014-06-18 10:11:00 10:11:46 00:00:46 
X647HBP 2014-06-18 10:12:01 10:18:06 00:06:05 
HV13LSJ 2014-06-18 10:12:18 10:12:54 00:00:36 
X553UYC 2014-06-18 10:13:29 10:17:51 00:04:22 
Y208WGO 2014-06-18 10:13:56 10:23:03 00:09:07 

команды SQL ниже:

SELECT 
    A.plate, 
    a.date, 
    a.time as 'start time', 
    b.time as 'end time', 
    timediff(B.time, A.time) as 'Journey time' 
FROM 
    (SELECT 
     x.plate, 
      date(x.timestamp) as 'date', 
      time(x.timestamp) as 'time', 
      COUNT(*) rank 
    FROM 
     anpr_1 x 
    JOIN anpr_1 y ON y.plate = x.plate 
     AND ((date(y.timestamp) < date(x.timestamp)) 
     OR (date(y.timestamp) = date(x.timestamp) 
     AND time(y.timestamp) <= time(x.timestamp))) 
    GROUP BY x.plate , date(x.timestamp) , time(x.timestamp)) a 
     JOIN 
    (SELECT 
     x.plate, 
      date(x.timestamp) as 'Date', 
      time(x.timestamp) as 'time', 
      COUNT(*) rank 
    FROM 
     anpr_2 x 
    JOIN anpr_2 y ON y.plate = x.plate 
     AND ((date(y.timestamp) < date(x.timestamp)) 
     OR (date(y.timestamp) = date(x.timestamp) 
     AND time(y.timestamp) <= time(x.timestamp))) 
    GROUP BY x.plate , date(x.timestamp) , time(x.timestamp)) b ON b.plate = a.plate AND b.rank = a.rank 
where 
    b.time > a.time 
     and a.date = '2014-06-18' 
     and b.date = '2014-06-18' 
     and timediff(B.time, A.time) <= '03:00:00' 
order by a.time; 

Хотя, вероятно, более сложный, эта команда хорошо работает для того, что мне нужно. Однако то, что я теперь хочу сделать, это создать еще один запрос, который объединит эти результаты в 15-минутные ячейки времени со средним средним, минимальным и максимальным временем прохождения и графом. так, например, 15 минут данных, приведенных выше, будет выглядеть следующим образом:

Timeslot Median  Min   Max Count 
10:00:00 00:02:50 00:00:36 01:48:51 25 
10:15:00 ??:??:?? ??:??:?? ??:??:?? ?? 

Я пробовал различные комбинации group by и UNIX_TIMESTAMPs и посмотрел на аналогичные проблемы, размещенные на этом сайте, но я еще не было много успех в том, чего я пытаюсь достичь. Есть ли что-нибудь, что вы могли бы предложить помочь?

+0

Вы действительно хотите вторую строку вашего результата, а не только результаты 15-минутных интервалов, когда данные на самом деле существует? –

+0

Данные, используемые в качестве примера, всего лишь один кусок 15 минут, весь набор данных на самом деле является целым 24-часовым периодом, я просто опустил его из вопроса, чтобы он был коротким и точным. При необходимости я могу предоставить целый день примерных данных. Обычно в каждом 15-минутном интервале времени имеется как минимум одна запись данных. – almg

+0

Нет, данных выборки должно быть достаточно. Самая большая проблема с запросом - медиана, поскольку MySQL не имеет такой функции. –

ответ

1

Вот решение со средним путешествием времени вместо медианы:

SELECT 
     `Date`, 
     FLOOR(
     ((60* 60 * HOUR(TIMEDIFF(Starttime, '10:00:00'))) 
     + (60 * MINUTE(TIMEDIFF(Starttime, '10:00:00'))) 
     + SECOND(TIMEDIFF(Starttime, '10:00:00')))/(15 * 60)) as intervalNo, 
     min(Journey_Time), max(Journey_Time), 
     SEC_TO_TIME(AVG(TIME_TO_SEC(Journey_Time))) as avgTime, 
     count(*) as Journeys 
FROM table 
GROUP BY 1,2 

Имейте в виду, что это основано на 10:00:00 каждый день. Просто измените это на любое другое время начала. Вы можете использовать функцию MySQL ADDTIME() для вычисления фактического интервала времени из интервалаNo (см. here).

EDID

Найдено компактная версия с 15-минутными Таймслотами:

SELECT 
    `Date`, 
    FLOOR(TIME_TO_SEC(TIMEDIFF(Starttime, '10:00:00'))/(15 * 60)) as intervalNo, 
    SEC_TO_TIME(FLOOR(TIME_TO_SEC(TIMEDIFF(Starttime, '10:00:00'))/(15 * 60)) * 15 * 60) 
       as TimeInterval, 

    min(Journey_Time), max(Journey_Time), 
    SEC_TO_TIME(AVG(TIME_TO_SEC(Journey_Time))), 
    count(*) as Journeys 

FROM table 
GROUP BY 1,2 
+0

Спасибо! Это большой скачок в правильном направлении и в основном делает то, что я ищу. Я изменил «10:00:00» на «00:00:00», чтобы дать мне то, что кажется полным днем ​​данных, но я не совсем уверен, где 'ADDTIME()' должен перейти в дать временные интервалы. кроме того, это может быть ошибка форматирования/типа данных с моей стороны, но вычисление avg возвращает немало значений NULL. – almg

+0

Каким типом данных является ваш Journey_Time col? ВРЕМЯ? – Benvorth

+0

Хорошо, обновил функцию avg() в моем ответе. [Здесь] (http://stackoverflow.com/questions/2217139/mysql-average-on-time-column) почему :-) – Benvorth

 Смежные вопросы

  • Нет связанных вопросов^_^