SQL 查找一组中两个值之间的时间差
SQL to find time difference between two values in a group
我有一个 sql table 如下所示。
+---------------------+--------+-------+
| 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 |
+---------------------+--------+-------+
我需要弄清楚项目从 st1 到 st2 等状态更改花费了多少时间..
最终输出 table 应如下所示。
+--------+------------+---------------+
| item | st1_to_st2 | st2_to_st3 | and so on
+--------+------------+---------------+
| a | x seconds| w-seconds |
| b | y-seconds| z-seconds |
+--------+------------+---------------+
你能帮我 sql 吗?
对于固定的状态列表,您可以使用window函数和聚合:
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
我有一个 sql table 如下所示。
+---------------------+--------+-------+
| 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 |
+---------------------+--------+-------+
我需要弄清楚项目从 st1 到 st2 等状态更改花费了多少时间..
最终输出 table 应如下所示。
+--------+------------+---------------+
| item | st1_to_st2 | st2_to_st3 | and so on
+--------+------------+---------------+
| a | x seconds| w-seconds |
| b | y-seconds| z-seconds |
+--------+------------+---------------+
你能帮我 sql 吗?
对于固定的状态列表,您可以使用window函数和聚合:
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