mysql - 如何获取值保持高于限制的时间

标签 mysql sql


我有一个温度计,它存储所有读数数据。
例子: http://sqlfiddle.com/#!9/c0aab3/9

这个想法是为了获得温度高于 85 华氏度时剩余的时间。

据我所知,我已投入了一切,但仍无法找到解决方案。 目前,我正在做的是获取超过 85 时的时间,然后获取下一个低值 85 来计算时间差。

如果温度连续5分钟保持在85度,数据可能会失败。
请问,这个计算方法是什么?

根据sqlfiddle的示例,显示的结果大于或等于85,但在某些情况下没有保持意味着低。 必须要从开始到最低点取那个峰值,时间以秒为单位计算,因此,我必须依次进行,直到结束。 然后添加所有秒数并得到时间。

enter image description here

最佳答案

基本答案(表格上没有修改)

我可以找到一种使用变量和一些操作它们的 IF 函数的方法。看看这是否适合您:

SET @currIndex = 1;
SET @indicator = FALSE;
SET @prevIndex = 0;

SELECT Q2.sen,
       MIN(Q2.subTime) as 'From', 
       MAX(Q2.subTime) AS 'To',
       TIMEDIFF(MAX(Q2.subTime), MIN(Q2.subTime)) as diff
    FROM (SELECT IF(Q1.temp < 85, 
                    IF(@prevIndex = @currIndex, 
                       (@currIndex := @currIndex +1) -1, 
                       @currIndex), 
                    @prevIndex := @currIndex) AS 'Ind', 
                 Q1.subTime,  
                 Q1.temp,
                 Q1.sen
              FROM (SELECT IF(sen_temp.temp < 85, 
                              (@indicator XOR (@indicator := FALSE)),
                              @indicator := TRUE) as ind,
                           s_time AS subTime, 
                           temp, 
                           sen
                        FROM sen_temp
                    ) AS Q1
              WHERE Q1.ind
          ) AS Q2
   GROUP BY Q2.`Ind`
   ORDER BY Q2.subTime;

这是一个SQL fiddle根据您自己的情况。

这个查询的主要问题是它的性能。由于表上没有ID,所以必须通过查询携带数据。


性能答案(需要修改表格)

经过大量优化工作,我最终向表中添加了一个 ID。它允许我只有一个子查询而不是 2 个,并且在子查询中携带更少的数据。

SET @indicator = FALSE;
SET @currentIndex = 0;

SELECT T1.sen, MIN(T1.s_time) as 'From', MAX(T1.s_time) AS 'To', 
       TIMEDIFF(MAX(T1.s_time), MIN(T1.s_time)) as diff
    FROM (SELECT id, (CASE WHEN (temp >= 85) THEN 
                        @currentIndex + (@indicator := TRUE)
                      WHEN (@indicator) THEN 
                        @currentIndex := @currentIndex + (@indicator := FALSE) + 1
                      ELSE 
                        @indicator := FALSE 
                      END) as ind
            FROM sen_temp
            ORDER BY id, s_date, s_time)  AS Q1
    INNER JOIN sen_temp AS T1 ON Q1.id = T1.id
    WHERE Q1.ind > 0
    GROUP BY T1.sen, Q1.ind

请查看this fiddle对于这个更高效的版本。


性能差异说明

创建 MySQL 查询时,性能始终是关键。如果很简单,查询将有效执行,并且您不应该遇到任何问题,除非遇到语法错误或其他优化问题,例如在未索引的字段上过滤或排序数据。

当我们创建子查询时,数据库会更难处理查询。原因很简单:它可能会使用更多的 RAM。当执行包含子查询的查询时,首先执行子查询(您可能会说“显然!”)。当执行子查询时,服务器需要为上层查询保留这些值,因此它会在 RAM 中创建一个临时表,以便在需要时可以查阅上层查询中的数据。尽管 RAM 相当快,但在处理大量数据时,速度似乎会慢很多。更糟糕的是,查询使数据库服务器处理大量数据,以至于 RAM 都装不下,迫使服务器使用慢得多系统的存储。

如果我们将子查询中生成的数据量限制到最小,然后仅在主查询中恢复所需的数据,则服务器用于子查询的 RAM 量可以忽略不计,并且查询运行得更快。

因此,子查询的数据量越小,整个查询的执行速度就越快。对于几乎所有“类似 SQL” 数据库来说都是如此。

Here's一本很好的读物,解释了如何优化查询

关于mysql - 如何获取值保持高于限制的时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48872718/

相关文章:

mysql - 将逗号分隔列表与 SQL 语句中的输入匹配

MySQL 内连接(带别名)

sql - 无法在 5.1.32 上创建具有 TRIGGER 权限的 MySQL 触发器

php - MySQL错误: Incorrect table definition; there can be only one auto column and it must be defined as a key

php - 如何使用正则表达式精确匹配 MySQL 中的记录?

mysql - 尝试使用 CASE 按字母顺序对数据库列进行排序

mysql - 同一张表上的SQL嵌套查询

PHP/MYSQL延迟更新查询

mysql - sql/存储过程在单词标签表中查找匹配记录

java - 将好友列表实现到数据库中的最佳方法? MySQL