【问题标题】:SQL to find time difference between two values in a groupSQL查找组中两个值之间的时间差
【发布时间】:2021-03-15 14:56:36
【问题描述】:

我有一个如下所示的 sql 表。

+---------------------+--------+-------+
|        time         | item   | state |
+---------------------+--------+-------+
| 2019-07-19 1:50:00 | a      |   st1 |
| 2019-07-19 2:51:00 | a      |   st2 |
| 2019-07-19 2:55:00 | b      |   st1 |
| 2019-07-19 2:59:00 | b      |   st2 |
| 2019-07-19 4:30:00 | a      |   st3 |
+---------------------+--------+-------+

我需要计算出 item 将状态从 st1 更改为 st2 等等..

最终的输出表应该是这样的。

+--------+------------+---------------+
| item   | st1_to_st2 |   st2_to_st3  | and so on
+--------+------------+---------------+
| a      |   x seconds| w-seconds     |
| b      |   y-seconds| z-seconds     |
+--------+------------+---------------+

你能帮我处理一下sql吗?

【问题讨论】:

  • 创建一个列数未定义的结果行是可能的,但费用很高。但通常这根本没有意义。也许你应该重新考虑你的概念

标签: mysql sql datetime subquery date-arithmetic


【解决方案1】:

对于固定的状态列表,可以使用窗口函数和聚合:

select item,
    sum(case when lag_state = 'st1' and state = 'st2' then timestampdiff(second, lag_time, time)) as st1_to_st2,
    sum(case when lag_state = 'st2' and state = 'st3' then timestampdiff(second, lag_time, time)) as st2_to_st3
from (
    select t.*,
        lag(time)  over(partition by item order by state) lag_time,
        lag(state) over(partition by item order by state) lag_state
    from mytable t
) t
group by item

如果您想要更通用的东西 - 即不会对状态进行硬编码 - 我建议将值放在行中而不是列中:

select item, lag_state, state, 
    sum(timestampdiff(second, lag_time, time)) as sum_diff
from (
    select t.*,
        lag(time)  over(partition by item order by state) lag_time,
        lag(state) over(partition by item order by state) lag_state
    from mytable t
) t
group by item, lag_state, state

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-05
    • 1970-01-01
    • 2021-01-02
    • 2022-12-20
    • 2020-01-11
    相关资源
    最近更新 更多