如何在表格的一个序列中获得当前和最后一个更大的值?

时间:2019-01-31 10:48:47

标签: mysql

我在MySQL中有一个带有列的InnoDB表'plant_alarm'

`plant_id` int(11) NOT NULL,
'alarm_code' var(20) NOT NULL,
`time` int(20) NOT NULL, [...]

因此每个id可以有多个时间戳,每个时间戳可以有多个id以及alarm_code。

我正在尝试建立一个查询,在该查询中我可以获取条目,如果有的话,可以按顺序输入最后一个较大的时间,因此它应返回例如:

Time    Plant id    Alarm Code
00:00      10             RUN
00:00      11             RUN
00:01      10             RUN
00:01      11             RUN
00:02      10             STOP
00:02      11             RUN
00:03      10             STOP
00:03      11             STOP
00:04      10             RUN
00:04      11             STOP
00:05      10             RUN
00:05      11             RUN

Alarm Start Time        Alarm End Time  |--|Plant id    Alarm Code
00:00 |------------------| 00:01             10            RUN
00:00 |------------------|00:02              11            RUN
00:02 |------------------| 00:03         10            STOP
00:03 |------------------| 00:04         11            STOP
00:04 |------------------| NULL              10            RUN
00:05 |------------------| NULL              11            RUN

我们尝试通过使用工厂ID和警报代码对数据进行分组来查找下一次和最短时间,但是整天它只返回1条警报,而且非常慢。

以下是我们到目前为止发现的MySQL查询:

SELECT 
    temp_plant_id,
    temp_alarm_code, 
    temp_date_time, 
    (   SELECT 
            MIN(temp_date_time) 
        FROM 
            plant_alarm_data_temp sub 
        WHERE 
            sub.temp_plant_id = main.temp_plant_id 
            and sub.temp_alarm_code = main.temp_alarm_code 
            and sub.temp_date_time > main.temp_date_time
    ) as nxttime
FROM plant_alarm_data_temp AS main

1 个答案:

答案 0 :(得分:0)

正确的解决方案是在INSERT上创建触发器触发,该触发器将每对Start / Stop事件转换为一个时间范围,并将其添加到表TIME_FRAMES中。触发器将检查:

  • 如果表TIME_FRAMES中有给定警报和工厂的打开时间间隔(意味着TIME_FRAMES.alarm_stop IS NULL),请为此时间间隔设置alarm_stop
  • 否则这是一个新的时间间隔-因此在表TIME_FRAMES中创建一条记录,其ALARM_START列等于该时间,并设置给定的警报代码和工厂ID

查询时间间隔而不是时间点将更容易非常


同时,您可以尝试以下查询(效率不高):

SELECT p1.time AS alarm_start, p2.time AS alarm_stop, p1.plant_id, p1.alarm_code
FROM
(SELECT (@row1 := @row1 + 1) AS rownum, time, alarm_code, plant_id 
FROM plant_alarm, (SELECT @row1 := 0) AS t1
ORDER BY plant_id,time) AS p1
LEFT JOIN
(SELECT (@row2 := @row2 + 1) AS rownum, time, alarm_code, plant_id 
FROM plant_alarm, (SELECT @row2 := 0) AS t2
ORDER BY plant_id,time) AS p2
ON p2.rownum = p1.rownum + 1
ORDER BY p1.plant_id, p1.time