MySQL计算数据范围内的周期

时间:2014-07-23 14:08:36

标签: php mysql sql

  • 我的MySQL表由电位器和硬件填充。
  • 将传感器更改数据的值添加到名为Pot的MySQL表列中。
  • Pot是包含随时间推移从电位计读取的值的列。
  • 此列中的值范围为760到1007.
  • 此列中的值不能立即从760跳到1007,它必须是连续的。

所以这就是表格的样子:

    ***Pot***
Time 1s -> 1007
Time 2s -> 987
Time 3s -> 909
Time 4s -> 887
time 5s -> 779
Time 6s -> 775
Time 7s -> 767
Time 8s -> 1004
Time 9s -> 1004
Time 10s -> 1004
Time 11s -> 1001
Time 12s -> 987
Time 13s -> 899

我添加的时间箭头表示硬件在时间1秒添加一个值,添加时间2秒987 ....在实验开始后7秒,添加767。

一旦达到较低值,传感器开始输入上限附近的值,如1007等。从高值开始,传感器开始再次将值返回到下限。可能有重复,但您可以看到随着时间的推移输入行。

我想要做的是找出传感器值的上限到下限的次数。

所以在这种情况下,循环次数的输出将是1而不是2,因为这些值尚未达到760ish被认为是2个循环。

select count(*)
from (select cycle, min(BBQ_Chicken) as minpot, maxpot as maxpot
      from (select *,
                   @cycle = if(pot >= 1000 and @state = 'bottom',
                               if(@state := 'top', @cycle + 1, @cycle + 1),
                               if(pot < 770, if(@state := 'bottom', @cycle, @cycle), @cycle)
                              ) as cycle
            from `SeInfo` t cross join
                 (select @state := 'bottom', @cyclestart) vars
            order by id
           ) p
     ) t
where minpot < 770 and maxpot >= 1000;

上面的代码在运行查询时没有返回任何行...有什么想法吗?

1 个答案:

答案 0 :(得分:1)

我认为您希望状态机能够跟踪某些事物是否最近达到了范围的顶部或底部。然后,您可以使用过渡到顶部来测量循环开始的时间。以下是有关周期的摘要信息:

select cycle, min(pot+0) as minpot, max(pot+0) as maxpot
from (select si.*,
             @cycle := if(pot >= 1000 and @state = 'bottom',
                          if(@state := 'top', @cycle + 1, @cycle + 1),
                          if(pot < 770, if(@state := 'bottom', @cycle, @cycle), @cycle)
                         ) as cycle
      from SeInfo si cross join
           (select @state := 'bottom', @cycle := 0) vars
      order by id
     ) si
group by cycle;

您可以将其用作子查询来获取符合条件的数字:

select count(*)
from (select cycle, min(pot+0) as minpot, max(pot+0) as maxpot
      from (select si.*,
                   @cycle := if(pot >= 1000 and @state = 'bottom',
                                if(@state := 'top', @cycle + 1, @cycle + 1),
                                if(pot < 770, if(@state := 'bottom', @cycle, @cycle), @cycle)
                               ) as cycle
            from SeInfo si cross join
                 (select @state := 'bottom', @cycle := 0) vars
            order by id
           ) si
      group by cycle
     ) si
where minpot < 770 and maxpot >= 1000;

请注意,这假设您有一个指定值排序的列。 SQL表表示无序集,因此您需要一个列来指定排序。

Here是SQL Fiddle,它正在发挥作用。