使用Sql Server 2008
所以我有一个名为States的表,它有这样的数据:
DateTime | skID | TZ | DomID | EventName | SKGrpID | State
--------------------------------------------------------------------------
2016-06-08 09:22:54.010 | 1234 | 1 | 222 | 0 | 4321 | 0
2016-06-08 09:22:54.000 | 1234 | 1 | 222 | 3 | 4321 | 3
2016-06-08 09:21:56.000 | 1234 | 1 | 222 | 8 | 4321 | 4
2016-06-08 09:19:00.000 | 1234 | 1 | 222 | 7 | 4321 | 4
2016-06-08 09:18:58.000 | 1234 | 1 | 222 | 4 | 4321 | 4
2016-06-08 09:13:06.000 | 1234 | 1 | 222 | 6 | 4321 | 6
2016-06-08 09:10:42.000 | 1234 | 1 | 222 | 4 | 4321 | 4
2016-06-08 09:10:40.000 | 1234 | 1 | 222 | 1 | 5555 | 1
2016-06-08 09:00:28.003 | 1234 | 1 | 222 | 1 | 4321 | 1
可以将行记录为接听电话的人的记录。如果国家是'4'这意味着他们正在通电话,如果是其他任何东西,那么他们不是。最古老的记录位于底部。所以9:10:42的第三条记录是通话开始,9:13:06的记录是通话结束(状态从4变为6)。
有时呼叫会持续多个事件。所以在9:18:58的记录中,呼叫开始并持续到记录在9:21:56(状态开始 - > 4,4,4,3< -End)
我想要一个查询以某种方式选择开始记录和结束记录,加入它们并获得持续时间。问题是我不知道如何根据状态从4改为其他东西。我也在努力弄清楚如何选择每个调用的每个开始(开始记录将是状态为4的记录,而前面的记录是其他东西(所以像状态1,4,3,6,4) ,5将是第二个,第5个记录将是呼叫开始,3和6将是呼叫的结束。))
理想的结果就像是
StartTime, EndTime, Duration, skID, TZ, DomID, SKGrpID, StartEvent, StartState, EndEvent, EndState
我能够通过查询所有行然后制作dicts并匹配调用方式来完成当前在python中的这个,但我想尽可能在SQL中做。这种选择甚至可能吗?
答案 0 :(得分:1)
这是一种方法:
select
max(case when RN = 1 then DateTime end) as StartTime,
max(case when RN = 2 then DateTime end) as EndTime,
max(case when RN = 1 then EventName end) as StartEvent,
max(case when RN = 2 then EventName end) as EndEvent
from
(
select
*,
row_number() over (partition by CallId order by DateTime) as RN
from
(
select
*,
sum(CallStatus) over (order by DateTime) as CallId
from
(
select
*
from
(
select
*,
lag(CallStatus) over (order by DateTime) as PrevCallStatus
from
(
select
DateTime,
State,
EventName,
case when State = 4 then 1 else 0 end as CallStatus
from #Table1
) A
) B
where CallStatus != PrevCallStatus
) C
) D
) E
group by CallId
这从最里面的派生表A
开始,该表用于分配呼叫状态1/0。表B
用于获取CallStatus的先前值,然后使用该值过滤掉具有相同CallStatus的行。因为CallStatus是1/0,所以它可以在运行总计中用于为每个调用计算单独的ID。因为来自它的数据总是包含2行,所以row_number用于为行分配一个数字(1 =开始,2 =结束),然后在最终选择中使用它来分别从开始行和结束行获取数据。
这没有你所有的领域,但至少它应该让你开始:)
这假设您始终拥有呼叫的结束记录,并且仅适用于SQL Server 2012或更高版本。对于旧版本,您需要为运行总计和滞后创建更复杂的内容。很可能光标是最好的选择。
答案 1 :(得分:0)
SELECT 'StartTime'
, 'EndTime'
, 'Duration'
, 'skID'
, 'TZ'
, 'DomID'
, 'SKGrpID'
, 'StartEvent'
, 'StartState'
, 'EndEvent'
, 'EndState';
如果那不是您的意思,请澄清。 ;-)