Mysql 计算每个状态的时间量

Mysql 计算每个状态的时间量,mysql,select,Mysql,Select,我有下表 时间戳是状态开始的时刻。 如果状态像第二行一样更改,则有些行不会添加新信息,可以忽略它们 我想使用mysql 5.7计算每个状态的总时间 | timeStamp | status | |------------------------------| | 2019-12-10 14:00:00 | 1 | | 2019-12-10 14:10:00 | 1 | // this row could be ignored | 2019-12-10

我有下表

时间戳是状态开始的时刻。 如果状态像第二行一样更改,则有些行不会添加新信息,可以忽略它们

我想使用mysql 5.7计算每个状态的总时间

|      timeStamp      | status |
|------------------------------|
| 2019-12-10 14:00:00 |   1    |  
| 2019-12-10 14:10:00 |   1    | // this row could be ignored
| 2019-12-10 14:00:00 |   2    | // more 24 hours in status 1
| 2019-12-11 14:10:00 |   2    | 
| 2019-12-12 14:00:00 |   1    | // more 24 hours in status 2
| 2019-12-14 14:00:00 |   2    | // more 48 hours in status 1
| 2019-12-16 14:10:00 |   2    |
| 2019-12-17 14:20:00 |   2    | 
| 2019-12-18 14:00:00 |   3    | // more 96 hours in status 2
| 2019-12-19 14:00:00 |   1    | // more 24 hours in status 3

我希望看到一张像贝娄这样的桌子

| status | amount_of_time |
|-------------------------|
|    1   |     72 hours   |
|    2   |     120 hours  |
|    3   |     24 hours   |

使这更复杂的是,状态没有按顺序排列:不是1、2、3。
在上面的示例中,它是:1、2、1、2、3、1,因此我不能使用MIN信息。

在子查询中获取以下行的时间戳,并计算与当前行的时间戳的差异:

select t1.status, timestampdiff(second,
  t1.timeStamp,
  (
    select min(t2.timeStamp)
    from mytable t2
    where t2.timeStamp > t1.timeStamp
  )
) as diff                     
from mytable t1;
这将返回:

| status | diff   |
| ------ | ------ |
| 1      | 600    |
| 1      | 86400  |
| 2      | 600    |
| 2      | 85800  |
| 1      | 172800 |
| 2      | 173400 |
| 2      | 87000  |
| 2      | 85200  |
| 3      | 86400  |
| 1      | NULL   |
从这里开始,这只是一个分组和汇总的问题:

结果:

| status | duratation_in_seconds |
| ------ | --------------------- |
| 1      | 259800                |
| 2      | 432000                |
| 3      | 86400                 |
如果希望时间以小时为单位,请将第一行更改为

select status, round(sum(diff)/3600) as duratation_in_hours
您将获得:

| status | duratation_in_hours |
| ------ | ------------------- |
| 1      | 72                  |
| 2      | 120                 |
| 3      | 24                  |
你可能想用地板代替圆形。你的问题不清楚

在MySQL 8中,您可以使用window函数获取下一行的时间戳:

select status, sum(diff) as duratation_in_seconds
from (
  select 
    status,
    timestampdiff(second, timeStamp, lead(timeStamp) over (order by timeStamp)) as diff
  from mytable
) x
group by status;

获取子查询中以下行的时间戳,并计算与当前行时间戳的差异:

select t1.status, timestampdiff(second,
  t1.timeStamp,
  (
    select min(t2.timeStamp)
    from mytable t2
    where t2.timeStamp > t1.timeStamp
  )
) as diff                     
from mytable t1;
这将返回:

| status | diff   |
| ------ | ------ |
| 1      | 600    |
| 1      | 86400  |
| 2      | 600    |
| 2      | 85800  |
| 1      | 172800 |
| 2      | 173400 |
| 2      | 87000  |
| 2      | 85200  |
| 3      | 86400  |
| 1      | NULL   |
从这里开始,这只是一个分组和汇总的问题:

结果:

| status | duratation_in_seconds |
| ------ | --------------------- |
| 1      | 259800                |
| 2      | 432000                |
| 3      | 86400                 |
如果希望时间以小时为单位,请将第一行更改为

select status, round(sum(diff)/3600) as duratation_in_hours
您将获得:

| status | duratation_in_hours |
| ------ | ------------------- |
| 1      | 72                  |
| 2      | 120                 |
| 3      | 24                  |
你可能想用地板代替圆形。你的问题不清楚

在MySQL 8中,您可以使用window函数获取下一行的时间戳:

select status, sum(diff) as duratation_in_seconds
from (
  select 
    status,
    timestampdiff(second, timeStamp, lead(timeStamp) over (order by timeStamp)) as diff
  from mytable
) x
group by status;