当值超过平均值时如何计数

xzlaal3s  于 2021-06-17  发布在  Mysql
关注(0)|答案(1)|浏览(278)

我正在尝试编写一个mysql查询来计算一个值与一个常量交叉的次数。最终的结果是我们将通过值的振幅和频率来确定值的相对“噪声”。min()和max()提供振幅。count()提供符合条件的样本数,但不提供该值的稳定性。我们目前正在使用MySQL5.7,但我们将转向提供窗口功能的MySQL8.0。像这样的

Select Count(Value) over (order by logtime ROWS 1 Proeeding <123 AND 1 Following > 123) WHERE logtime BETWEEN...;

谢谢你的帮助。

SELECT Count(Value) WHERE Value > 123 AND logtime BETWEEN...;

SELECT Count(Value) WHERE Value < 123 AND logtime BETWEEN...;
km0tfn4u

km0tfn4u1#

在8.0之前的mysql版本中不提供窗口函数
在mysql 5.7中,我们可以通过在精心编制的查询中使用用户定义的变量来模拟一些窗口函数。mysql参考手册对在这样的上下文中使用用户定义的变量给出了明确的警告。我们所依赖的是无法保证的行为。
但作为我用来实现特定结果的模式的一个例子:

SELECT SUM(c.crossed_avg) AS count_crossed_avg
  FROM ( 
         SELECT IF( ( @prval > a.avg_ AND t.value < a.avg_ ) OR 
                    ( @prval < a.avg_ AND t.value > a.avg_ )
                ,1,0) AS crossed_avg
              , @prval := t.value AS value_
           FROM mytable t
          CROSS
           JOIN ( SELECT 123 AS avg_ ) a
          CROSS
           JOIN ( SELECT @prval := NULL ) i
          WHERE ...
          ORDER BY t.logtime

       ) c

要解开这个包,首先关注内联视图查询;也就是说,忽略select sum() Package 器查询,只运行内联视图查询。
我们按顺序排列 logtime 这样我们就可以按顺序处理行了。
我们将当前行的值与前一行的值进行比较。如果一个高于平均值,另一个低于平均值,则返回1,否则返回0。
将当前值保存到用户定义的变量中,以便比较下一行(注:操作顺序很重要;我们依赖mysql在评估 IF() 功能。
当一行值正好等于平均值(例如一系列值)时,示例查询不处理边缘情况 124.4 < 123.0 < 122.2 . (我们可能需要考虑改变比较,以便其中包括等式。 < 以及 >= .

相关问题