Как считать, когда значение пересекает среднее - PullRequest
0 голосов
/ 03 января 2019

Я пытаюсь написать запрос MySQL, который бы подсчитывал, сколько раз значение пересекает константу. Конечный результат - мы пытаемся определить относительный «шум» значения по амплитуде и частоте значения. MIN () и MAX () обеспечивают амплитуду. Count () дает количество выборок, которые соответствуют критериям, но это не обеспечивает, насколько стабильно это значение. В настоящее время мы используем MySQL 5.7, но мы перейдем к MySQL 8.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...;

1 Ответ

0 голосов
/ 03 января 2019

Оконные функции недоступны в версиях MySQL до 8.0

В 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 () и выполните только запрос встроенного представления.

Мы упорядочиваем строки по logtime, чтобы мы могли обрабатывать строки по порядку.

Мы сравниваем значение в текущей строке со значением из предыдущей строки. Если один выше среднего, а другой ниже среднего, то мы возвращаем 1, иначе мы возвращаем 0.

Сохранить текущее значение в пользовательскую переменную для сравнения следующей строки. (Примечание: порядок операций важен; мы зависим от MySQL, чтобы выполнить это назначение после оценки функции IF().


Пример запроса не обращается к краевому случаю, когда значение строки точно равно среднему, например, последовательность значений 124.4 <<code>123.0 <<code>122.2. (Мы могли бы рассмотреть возможность изменения сравнений, чтобы включить равенство, например, < и >=.

...