1

我有一个这样的 MySQL 表:

ID - Time - Value

我得到每对 ID,Time(按 ID 分组),其中 Value 大于某个阈值。所以基本上,我得到的每个 ID 至少有一次大于阈值。查询如下所示:

SELECT ID, Time FROM mydb.MYTABLE
WHERE Value>%s AND Time>=%s AND Time<=%s
GROUP BY ID

编辑:时间检查允许在我选择的所有数据之间的时间范围内进行操作;它与我要问的无关。

它工作得很好,但现在我想添加一些过滤:我希望它避免那些时间值大于阈值(让我们称之为警报),如果警报还没有发生在之前或之后的时间。我的意思是:如果警报发生在一个单独的、孤立的时刻而不是两个连续的时刻,我会认为这是一个错误警报,并避免在查询响应中返回它。

当然,我可以通过调用每个 Id 来检查这一点,但我想在单个查询中执行此操作以使其更快。我想我可以使用条件,但我在 MySQL 上没有这种专业知识。

有什么帮助吗?

EDIT2:阈值 = 10 的示例

ID - Time - Value
1  - 2004 -   9
1  - 2005 -  11
1  - 2006 -   8
2  - 2107 -  12
2  - 2109 -  13
3  - 3402 -  11
3  - 3403 -  12

在此示例中,只有 ID 3 应该是有效警报,因为此 ID 的 2 个连续时间值的值 > 阈值。ID 1 有一个单独的、隔离的警报,所以它应该是过滤器。对于 ID 2,有 2 个警报,但不是连续的,因此也应过滤。

4

2 回答 2

1

像这样的东西:

10 - is a threshold
0 - minimum of the time period
100000 - maximum of the time period


select ID, min(Time)

from
(
SELECT ID, Time,

       (select max(time) from t 
           where Time<t1.Time
           and Id=t1.Id
           and Value>10) LAG_G,
       (select max(time) from t 
           where Time<t1.Time
           and Id=t1.Id
           and Value<=10) LAG_L,
       (select min(time) from t 
           where Time>t1.Time
           and Id=t1.Id
           and Value>10) LEAD_G,
       (select min(time) from t 
           where Time>t1.Time
           and Id=t1.Id
           and Value<=10) LEAD_L

FROM t as t1
WHERE Value>10 AND Time>=0 AND Time<=100000
) t3
where ifnull(LAG_G,0)>ifnull(LAG_L,0)
      OR
      ifnull(LEAD_G,100000)<ifnull(LEAD_L,100000)

GROUP BY ID

SQLFiddle 演示

此查询适用于搜索附近的记录。

如果您需要按评论中提到的时间(+1,-1)搜索记录,请尝试以下查询:

select ID, min(Time) from t as t1
where Value>10
      AND Time>=%s2 AND Time<=%s1
  and 
   ( 
      Exists(select 1 from t where Value>10 
                              and Id=t1.Id
                              and Time=t1.Time-1) 
      OR 

      Exists(select 1 from t where Value>10 
                              and Id=t1.Id
                              and Time=t1.Time+1) 
   )  
group by ID

SQLFiddle 演示

于 2013-07-25T10:50:59.830 回答
0

这样的警报?

SELECT ID, Time , count(if(value>%treshold ,1,0)) alert_active
FROM mydb.MYTABLE
WHERE Value>%s3 AND Time>=%s2 AND Time<=%s1
GROUP BY ID;

我不完全明白:

在此示例中,只有 ID 3 应该是有效警报,因为此 ID 的 2 个连续时间值的值 > 阈值。ID 1 有一个单独的、隔离的警报,所以它应该是过滤器。对于 ID 2,有 2 个警报,但不是连续的,因此也应过滤。

我猜你想要过滤警报:

SELECT ID, Time 
FROM mydb.MYTABLE
WHERE Value>%s3 AND Time>=%s2 AND Time<=%s1
GROUP BY ID
having value<%treshold;
于 2013-07-25T10:49:38.853 回答