完全重写基于新的信息。我是如何处理这个问题的,首先是查询最内层的查询,以便根据HomeID = 111获取我们关心的所有记录,并确保它们按照序列ID(HomeID,Sequence上的索引)进行了预先排序。众所周知,打电话是通过接电话开始的 - eventID = 12,获得拨号音 - eventid = 22,拨出电话,有人接听电话,直到电话重新开机 - eventid = 30) 。如果它是一个挂断(eventid = 13),我们想忽略它。
我不知道你为什么要看序列#在当前调用之前,不知道它是否真的有方位。它看起来像你只是试图完成呼叫,持续时间有多长。也就是说,我将删除LEFT JOIN Phone_Event的部分和相应的WHERE子句。它可能在那里,而你只是想弄明白这一点。不管怎样,回到逻辑上。最内在保证呼叫顺序。您不会同时拨打两个电话。因此,通过首先获取它们,然后加入SQLVars(为查询创建内联变量@NextCall)。其目的是为了识别每次新的呼叫即将开始(EventID = 12)。如果是这样,请记下序号,并保存。这将保持不变,直到下一次呼叫,所有其他“事件ID”将具有相同的“起始序列ID”。另外,我正在寻找其他事件......事件= 22,根据启动顺序+1并将其设置为标志。然后,基于呼叫开始的最大时间(只在eventid = 12时设置)和呼叫结束(eventid = 30),最后是根据您的检查挂断(eventid = 13)的标志,即:如果是挂断电话而没有连接,则不要考虑通话。
通过分组,我本质上已经将每个呼叫汇总到自己的线路中......按家庭ID和用于发起实际电话呼叫的序列号进行分组。一旦THAT完成,我可以查询数据并计算自开始/结束时间在同一行以来的通话持续时间,而不涉及自我自我加入。
最后,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)
装置看一看的事件ID。如果它是12(即:摘机),则抓取该条目的序列号。这将成为另一个呼叫的新“起始序列”。如果没有,只要保留最后设置的值即可,因为它是正在进行的呼叫的延续。现在,让我们看看一些模拟数据,以帮助更好地说明所有列
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保持所有针对给定的叫“群”的顺序条目在一起,所以你不必只是使用大于跨度信息或小于...它总是遵循一定的“事件”路径,所以无论是什么时候开始呼叫都是其余事件的基础,直到下一次呼叫开始,那么这个序列就被抓到了这个组呼。
是啊,它有很多的把握..但希望现在更易消化为你:)
看起来像邮票的指标将有助于 – Randy
的主键(序列,首页)。还有(Sequence,Home),EventId和HomeId的索引。 – ethrbunny
abs(timediff(pe0.Stamp,pe1.Stamp))< - 这对于性能不是很好。 – JohnFx