полностью переписан на основе новой информации. Как я подошел к этому, нужно было начать с самого внутреннего запроса, чтобы все записи, о которых мы заботимся, основывались исключительно на HomeID = 111 и следили за тем, чтобы они были предварительно отсортированы по идентификатору последовательности (указатель на HomeID, Sequence). Как мы все знаем, телефонный звонок начинается, поднимая телефон - eventID = 12, получая гудок - eventid = 22, набирающий номер и кто-то, отвечающий, пока телефон не вернется на крючок - eventid = 30) , Если это зависание (eventid = 13), мы хотим игнорировать его.
Я не знаю, почему вы смотрите на последовательность # PRIOR на текущий вызов, не знаете, имеет ли он какой-либо подшипник. Похоже, вы просто пытаетесь получить завершенные звонки и как долго длится. Тем не менее, я бы удалил часть LEFT JOIN Phone_Event и соответствующее предложение WHERE. Возможно, это было, пока вы просто пытались понять это.
В любом случае, вернемся к логике. Внутреннее большинство гарантирует последовательность вызовов по порядку. У вас не будет двух одновременных вызовов. Поэтому, сначала получив их в порядке, я затем присоединяюсь к SQLVars (который создает встроенную переменную @NextCall для запроса). Цель этого - идентифицировать каждый раз, когда начнется новый вызов (EventID = 12). Если да, возьмите то, что есть в номере последовательности, и сохраните его. Это будет оставаться неизменным до следующего вызова, поэтому все остальные «идентификаторы событий» будут иметь одинаковый «идентификатор начальной последовательности». Кроме того, я ищу другие события ... событие = 22 на основе стартовой последовательности +1 и установки ее как флага. Затем максимальное время в зависимости от начала вызова (устанавливается только в случае eventid = 12) и завершения вызова (eventid = 30) и, наконец, флаг, основанный на вашей проверке для зависания (eventid = 13), т.е. : не рассматривайте вызов, если это зависание и никакого соединения.
Выполняя группу, я по существу свернул каждый вызов в свою линию, сгруппированный по идентификатору дома, и порядковый номер, используемый для инициирования фактического телефонного звонка. После того, как это будет сделано, я могу затем запросить данные и вычислить длительность вызова, так как время начала/окончания находится в одной и той же строке, при этом не включается самоизоляция.
Наконец, предложение where ... Вызвать любые телефонные звонки, которые были HANG UP.Опять же, я не знаю, нужен ли вам по-прежнему элемент того, что было временем стартового вызова последнего события окончания.
SELECT
PreGroupedCalls.*,
timediff(PreGroupedCalls.CallEndTime, PreGroupedCalls.CallStartTime) CallDuration
from
(SELECT
Calls.HomeID,
@NextCall := @NextCall + if(Calls.EventID = 12, Calls.Sequence, @NextCall) as NextNewCall,
MAX(if(Calls.EventID = 12, Calls.Stamp, 0)) as CallStartTime,
MAX(if(Calls.EventID = 30, Calls.Stamp, 0)) as CallEndTime,
MAX(if(Calls.EventID = 22 and Calls.Sequence = @NewCallFirstSeq +1, 1, 0)) as HadDTMFEntry,
MAX(if(Calls.EventID = 13 and Calls.Sequence = @NewCallFirstSeq +1, 1, 0)) as WasAHangUp
from
(select pe.HomeId,
pe.Sequence,
pe.EventID,
pe.Stamp
from
Phone_Events pe
where
pe.HomeID = 111
order by
pe.Sequence) Calls,
(select @NextCall := 0) SQLVars
group by
Calls.HomeID,
NextNewCall) PreGroupedCalls
LEFT JOIN Phone_Event PriorCallEvent
ON PreGroupCalls.NextNewCall = PriorCallEvent.Sequence -1
where
PreGroupedCalls.WasHangUp = 0
AND (PriorCallEvent.Sequence IS NULL
OR abs(timediff(PriorCallEvent.Stamp, PreGroupedCalls.CallStartTime)) > 10)
КОММЕНТАРИЙ ОТ ОБРАТНОЙ СВЯЗИ/ОШИБКИ сообщил
Чтобы попытаться исправить двойной ошибки, вы, очевидно, нужно будет сделать небольшое изменение в SQLVARS выберите .. попробуйте следующее
(выберите @NextCall: = CAST (0 как INT)) SQLVars
Теперь, что делает IF() ... Давайте посмотрим.
@NextCall + если (Calls.EventID = 12, Calls.Sequence, @NextCall)
средства взглянуть на события с кодом. Если это 12 (то есть: снятие трубки), возьмите все номера последовательности для этой записи. Это станет новой «Start Sequence» другого вызова. Если нет, просто сохраняйте все, что было установлено последним значением, поскольку оно является продолжением текущего вызова. Теперь давайте посмотрим на некоторые смоделированных данных, чтобы помочь лучше проиллюстрировать все столбцы
Original data Values that will ultimately be built into...
HomeID Sequence EventID Stamp @NextCall
111 1 12 8:00:00 1 beginning of a new call
111 2 22 8:00:01 1 not a new "12" event, keep last value
111 3 30 8:05:00 1 call ended, phone back on hook
111 4 12 8:09:00 4 new call, use the sequence of THIS entry
111 5 22 8:09:01 4 same call
111 6 13 8:09:15 4 same call, but a hang up
111 7 30 8:09:16 4 same call, phone back on hook
111 8 12 8:15:30 8 new call, get sequence ID
111 9 22 8:15:31 8 same call...
111 10 30 8:37:15 8 same call ending...
Now, the query SHOULD create something like this
HomeID NextNewCall CallStartTime CallEndTime HadDTMFEntry WasAHangUp
111 1 8:00:00 8:05:00 1 0
111 4 8:09:00 8:09:16 1 1
111 8 8:15:30 8:37:15 1 0
Как вы можете видеть, @NextCall сохраняет все последовательные записи для данного вызова «сгруппированных» вместе, так что вы не должны просто используйте информацию больше, чем информацию о расстоянии или меньше ... Она всегда будет следовать определенному пути «событий», поэтому все, что запустило вызов, является основой для остальных событий, пока не будет запущен следующий вызов , то THAT-последовательность захватывается для группового вызова THAT.
Да, его много, чтобы понять .. но, надеюсь, теперь более удобоваримой для вас :)
выглядит как индекс на штемпеле будет полезно – Randy
Первичный ключ (последовательность, Home). Существуют также индексы (Sequence, Home), EventId и HomeId. – ethrbunny
abs (timediff (pe0.Stamp, pe1.Stamp)) <- это не может быть хорошо для производительности. – JohnFx