Вторая версия кода не работает по довольно непонятной причине.Эта часть:
else @count := 1
... имеет выражение, которое не имеет динамического компонента.MySql оптимизирует свой план выполнения таким образом, что он не выполняет это назначение во второй раз, а просто возвращает текущее значение @count
.Это связано с тем, что переменные MySql действительно не предназначены для изменения во время выполнения запроса.Когда вы все еще решаете использовать этот побочный эффект, вы должны знать о таком поведении «оптимизации».
Вы можете попытаться заставить MySql выполнять присваивание каждый раз.Это можно сделать, включив ссылку на переменную или поле в назначенное выражение.Например, вы можете использовать := if(@count, 1, 1)
вместо := 1
.Результат тот же (всегда 1), но теперь он будет переоцениваться и присваиваться каждый раз, когда он встречается:
where (case when @prev = (@prev := Num)
then @count := @count + 1
else @count := if(@count, 1, 1)
end) >= 3
Вы можете думать о других альтернативных выражениях, таких как := 1+Num*0
, до тех пор, покапоскольку есть ссылка на некоторую переменную / поле, это решит проблему.
Глядя на первую предоставленную вами версию запроса, вы увидите, что там выражение, присвоенное @count
, уже имеет такоединамическое содержимое.
В общем, установка переменных в запросе не рекомендуется, и будущие версии MySql могут больше не поддерживать его, как указано в Справочном руководстве :
Предыдущие выпуски MySQL позволяли присваивать значение пользовательской переменной в операторах, отличных от SET
.Эта функциональность поддерживается в MySQL 8.0 для обратной совместимости, но подлежит удалению в будущем выпуске MySQL.