0

似乎我的间隙检测只是拾取我设置为时间差的任何内容,并根据它在每个间隔进行。

所以这里是我的数据结构和我所追求的解释:

我有一个这样设置的数据库:

(Schema Name)
Historical
     -CID      int UQ AI NN 
     -ID       Int PK
     -Location Varchar(255)
     -Status   Varchar(255)
     -Time     datetime

我的数据看起来像这样(示例 5 行用于选定的 ID)

 433275 | 97  | MyLocation | OK | 2013-08-20 13:05:54
 433275 | 97  | MyLocation | OK | 2013-08-20 13:00:54
 433275 | 97  | MyLocation | OK | 2013-08-20 12:25:54
 433275 | 97  | MyLocation | OK | 2013-08-20 12:20:54
 433275 | 97  | MyLocation | OK | 2013-08-20 12:15:54

在上述情况下,您会注意到我缺少 ID 97 的 12:25:54 -> 13:00 的数据。我正在尝试编写一份报告,告诉我:停机时间的开始,停机时间的持续时间,和停机时间结束(我一直在 php 中通过将 timediff 添加到 Time 来处理)

这是我现在的代码(php -> mysql)(不工作):

        select *from (
            SELECT
            y.*,
            TIMESTAMPDIFF(MINUTE, @prevDT, `Time`) AS timedifference,
            @prevDT := `Time`
            FROM ddHistorical y,
            (SELECT @prevDT:=(SELECT MIN(`Time`) FROM ddHistorical)) vars
            Where ID  = '". mysql_real_escape_string($ID)."'
            HAVING timedifference > 16
          ) s
          order by Time desc
          Limit 25";
4

2 回答 2

1

您需要两个级别的子查询:

SELECT *
FROM (
    SELECT  y.*,
            TIMESTAMPDIFF(MINUTE, @prevDT, `Time`) AS timedifference,
            @prevDT := `Time`
            FROM (SELECT *
                  FROM ddHistorical
                  WHERE ID = '97'
                  ORDER BY `Time`) y,
                 (SELECT @prevDT:=(SELECT MIN(`Time`) FROM ddHistorical)) vars) z
WHERE timedifference > 16
LIMIT 25

我实际上不确定为什么需要最外层。我尝试不使用它(即以 开头SELECT y.*)并使用HAVING timedifference > 16. 出于某种原因,这报告了一行带有timedifference = 45. 但是如果我删除了该HAVING子句,它会显示所有行,间隔报告为 35 分钟。通常,两者之间没有区别

SELECT ... HAVING <cond>

SELECT * FROM (SELECT ...) WHERE <cond>

我不确定为什么这个查询违反了规则——我怀疑它与用户变量有关。

编辑:

我想我已经弄清楚为什么它不能与HAVING. MySQL 显然在计算timedifference每一行的列并丢弃该行时立即评估该条件。当 时timedifference <= 16,它不会费心计算SELECT子句中的其余列,所以它永远不会@prevDT := Time。所以在它超过那个条件之前,它总是与 比较MIN(Time)

timedifference检查移动到外部查询中会强制它在过滤之前计算所有差异。

SQLFIDDLE

于 2013-08-24T00:46:08.737 回答
0

请试试这个:

"
SELECT y.*,
       TIMESTAMPDIFF(MINUTE, y.prevDT, y.`Time`) AS timedifference
  FROM (SELECT w.*, (SELECT MAX(x.`Time`)
                       FROM ddHistorical x
                      WHERE x.ID = w.ID
                        AND x.`Time` < w.`Time`) AS prevDT
          FROM ddHistorical w
         WHERE w.ID  = '". mysql_real_escape_string($ID)."') y
 WHERE TIMESTAMPDIFF(MINUTE, y.prevDT, y.`Time`) > 16
 ORDER BY y.`Time` DESC
 LIMIT 25";
于 2013-08-24T01:51:59.317 回答