改变价值运行总时间

时间:2013-07-26 10:08:27

标签: sql postgresql

我有一个程序可以定期将用户移动数据连接的详细信息(信号强度,网络技术类型等)记录到PostgreSQL中的单个表中。表中的相关字段是;

networkmedium.id
networkmedium.date_time
networkmedium.medium_type

示例表可能看起来像;

0  |  2013-07-26 08:00:01  | 3G
1  |  2013-07-26 08:00:02  | GPRS
2  |  2013-07-26 08:00:06  | 3G
3  |  2013-07-26 08:00:10  | 3G
4  |  2013-07-26 08:00:16  | GPRS

我试图从这些数据中得出在特定媒体类型(即GPRS,3G等)上花费的总持续时间,并且我遇到了困难。

在上面的例子中,我需要r1和r0,r2和r1,r3和r1,r4和r3之间的时差,然后将它们加在一起按medium_type分组,但我陷入了最好的状态关于这个。

提前致谢, 崔佛

2 个答案:

答案 0 :(得分:2)

试试这个:

with CTE1 as
(
    select
        *,
        lead(date_time) over (order by date_time asc) as next_date_time
    from networkmedium
    order by date_time asc
)
select C1.medium_type, sum(date_part('second', C1.next_date_time - C1.date_time))
from CTE1 as C1
group by C1.medium_type

MEDIUM_TYPE |    SUM
--------------------
GPRS        |      4
3G          |     11

SQL FIDDLE EXAMPLE

更复杂的方法

with CTE1 as
(
    select
        *,
        lag(medium_type) over (order by date_time asc) as prev_medium_type
    from networkmedium
    order by date_time asc
), CTE2 as
(
    select *, row_number() over(order by date_time) as row_num
    from CTE1
    where prev_medium_type <> medium_type or prev_medium_type is null
)
select C1.medium_type, sum(date_part('second', C2.date_time - C1.date_time)) as cnt
from CTE2 as C1
    left outer join CTE2 as C2 on C2.row_num = C1.row_num + 1
group by C1.medium_type

SQL FIDDLE EXAMPLE

答案 1 :(得分:0)

我认为也可以采用r3-r2,它会给出相同的结果,不是吗?如果是这样,那么我认为这样做了。 尚未测试

SELECT t.medium_type, t.sum(duration) FROM ( SELECT n2.date_time - n1.date_time as duration FROM networkmedium n1 INNER JOIN networkmedium n2 on n2.id = n1.id+1 ) as t GROUP BY medium_type