【问题标题】:MySQL query to evaluate aggregate duration of time something is "on"MySQL 查询以评估某事物“开启”的总持续时间
【发布时间】:2010-02-10 15:16:39
【问题描述】:

我在表格中有一系列带时间戳的开/关数据,代表开/关状态,或状态“开始”的点

00:00:00    0
04:00:00    1
08:00:00    0
09:00:00    1
15:00:00    0
20:00:00    1
23:59:59    0

我需要计算(比如说)开启状态在 24 小时内的总持续时间。

在这个简化的示例中,总持续时间 = 1 是 (04:00:00->08:00:00, 09:00:00->15:00:00, 20:00:00->23:59:59 即 13:59:59 大约 14 小时

我无法确定这是否可以单独在 SQL 中完成,或者我正在使用的底层框架 (django) 是否需要根据返回的数据来执行此操作。如果可能的话,我显然更愿意让数据库来完成繁重的工作,因为我们可能还需要在单独的 stats 包中使用 SQL。

我不清楚我是否可以对选择中的上一个或下一个元素进行操作,我是一个自信的 SQL 用户,但看不到从哪里开始这个或通用方法,有什么想法吗?

我真的很想在单个查询中使用这个,或者我缺少一些其他巧妙的计算方式!

【问题讨论】:

  • 首先,我会设计表格,使 ON 和 OFF 状态时间在不同列的同一行上,那么这个任务将是微不足道的。如果这对您来说是不可能的,那么您需要进行大量的黑客攻击才能完成它:)

标签: mysql datetime math datediff temporal


【解决方案1】:

MySQL 中没有row_number(),但是你可以做一个双连接来搜索上一行:

select 
    sum(case when cur.state = 0 then 0
        else subtime(cur.timeCol, prev.timeCol)
        end) as TotalOnTime
from YourTable cur
join YourTable prev
    on prev.timeCol < cur.timeCol
left join YourTable inbetween
    on prev.timeCol < inbetween.timeCol
    and inbetween.timeCol < cur.timeCol
where inbetween.timeCol is null;

在 MySQL 中,您还可以使用变量,在这种情况下可能更有效:

set @total := '00:00:00';
set @lasttime := '00:00:00';

select 
    @total := addtime(@total, case 
        when state = 0 then 0
        when @lasttime is null then 0
        else subtime(timeCol, @lasttime)
        end)
,   @lasttime := timeCol
from YourTable
order by timeCol;

select 'Result = ', @total;

创建和填充测试表的代码:

DROP TABLE IF EXISTS YourTable;
CREATE TABLE YourTable (
   timeCol time,
   state bit
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

insert into YourTable values ('00:00:00',    0);
insert into YourTable values ('04:00:00',    1);
insert into YourTable values ('08:00:00',    0);
insert into YourTable values ('09:00:00',    1);
insert into YourTable values ('15:00:00',    0);
insert into YourTable values ('20:00:00',    1);
insert into YourTable values ('23:59:59',    0);

【讨论】:

  • 这个查询的复杂性让我想知道如果在代码中而不是在 SQL 中完成,这是否会更有效。但看起来它会起作用。
  • 我想我通过变量示例得到了你要去的地方,而且我想我更接近于你的帮助。我不熟悉@lasttime var之前的句点(“。”)前缀,这有什么作用?我在使用这种语法时遇到了错误,我在手册中找不到它的含义。
  • @Aitch: 下一栏应该是, 逗号
  • 我认为会是这样,但想知道我是否错过了一些古怪的 mysql 速记缩写 :) 只是调整了新代码,在你的建议下,我得到了一些令人鼓舞的结果,按照我的额外标准工作;完成后将发布调查结果以确保其完整性
猜你喜欢
  • 2013-10-29
  • 1970-01-01
  • 2019-08-02
  • 1970-01-01
  • 1970-01-01
  • 2023-01-10
  • 1970-01-01
  • 2016-02-23
  • 1970-01-01
相关资源
最近更新 更多