Оконные функции недоступны в версиях 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. (Мы могли бы рассмотреть возможность изменения сравнений, чтобы включить равенство, например, <
и >=
.