Php 查找重叠值的时间总和
我已经为这个问题挣扎了几天。我有一台机器可能有错误。在数据库中,我有出现错误时unix时间的开始和结束时间,以及5-12的错误号类型。我遇到的问题是,多个错误可能同时发生并重叠 我的桌子看起来像这样:Php 查找重叠值的时间总和,php,mysql,math,Php,Mysql,Math,我已经为这个问题挣扎了几天。我有一台机器可能有错误。在数据库中,我有出现错误时unix时间的开始和结束时间,以及5-12的错误号类型。我遇到的问题是,多个错误可能同时发生并重叠 我的桌子看起来像这样: id| type | from | to 1| 6 | 1417179933 | 1417180006 2| 6 | 1417180035 | 1417180065 3| 9 | 1417180304 | 1417180409 4
id| type | from | to
1| 6 | 1417179933 | 1417180006
2| 6 | 1417180035 | 1417180065
3| 9 | 1417180304 | 1417180409
4| 6 | 1417180662 | 1417184364
5| 8 | 1417180662 | 1417186832
6| 9 | 1417180662 | 1417184364
7| 12 | 1417180662 | 1417184364
8| 6 | 1417184364 | 1417186832
9| 9 | 1417184364 | 1417188054
我需要找到这台机器的总错误持续时间。我无法将上表中的所有差异相加,因为在同一时间间隔内可能出现两个或多个错误。记录按升序排序
我的猜测是将每个记录的开始和结束时间与之前的记录进行比较,然后找出以秒为单位的差异。但是,此表可能会随着时间的推移而增长,在其中搜索是一个问题
在PHP或MySQL中,有没有一种聪明的方法可以找出机器不工作的总时间,可能是几分钟?这里有一种计算时间间隔总和的一般方法,考虑到潜在的重叠,假设时间间隔按其较低的值排序 2个案例 当添加两个间隔[a,b]和[c,d]时,因此d-c+b-a可以计算它们的重叠两次 如果重叠不为零,则其值为minb,d-maxa,c。由于您在间隔开始时对项目进行了排序,因此您知道maxa,c==c
如果重叠为0,则为非数据库方法。可能会对数据库进行修改
Start Finish
10 13
12 15
16 18
将开始时间和完成时间合并到一个带有开始标志的排序列表或数组中
Time IsStart
10 Yes
12 Yes
13 No
15 No
16 Yes
....
使ActiveCounter=0,遍历列表。
如果启动,则递增ActiveCounter,否则递减
当ActiveCounter变为>0时,错误间隔开始,
当ActiveCounter变为=0时,错误间隔结束
Time ActCnt
10 1 //error state begins
12 2 //it continues
13 1 //still continues
15 0 //the end! T = 15-10 = 5
16 1 //new error state begins
从彼得那里偷一个主意
选择SUMto-from/60作为表中的allTime?或者,如果这两个错误重叠,那么您只需要计算其余的?好吧,在这个示例中,检查后可能有两个错误重叠,没有更多,但在实际表中,它可以是n个重叠。因此,只应计算不重叠的差异。我说得对吗?哦,我明白了。然后我误解了你的问题。4票?有些问题正好抓住了时代精神,不是吗-期望的结果是什么样的?这是一个答案吗?我不相信,不是吗?这在PHP中很容易做到,这就是所要求的。我敢肯定,这比MySQL要简单。我可能不会编写复制/粘贴代码,但除此之外,还有什么困扰着你呢?@草莓我添加了一个3v4l的链接,这样你就可以看到它的工作原理:好了,现在我确信了-
Time ActCnt
10 1 //error state begins
12 2 //it continues
13 1 //still continues
15 0 //the end! T = 15-10 = 5
16 1 //new error state begins
SELECT SUM(seconds) total
FROM
(
SELECT MAX(to_date) - MIN(from_date) seconds
FROM
(
SELECT from_date, to_date,
@g := IF(@e BETWEEN from_date AND to_date OR to_date <= @e, @g, @g + 1) g,
@e := to_date
FROM my_table CROSS JOIN
(
SELECT @g := 0, @e := NULL
) i
ORDER BY from_date, to_date
) q
GROUP BY g
) q;