Существует проблема с решением Quassnoi (помечен как лучший ответ).
У меня такая же проблема (т.е. имитация функции окна SQL в MySQL), и я использовал ее для реализации решения Quassnoi, используя пользовательские переменные для хранения предыдущего значения строки ...
Но, может быть, после обновления MySQL или чего-то еще мой запрос больше не работал. Это связано с тем, что порядок вычисления полей в SELECT не гарантируется. Назначение @class может быть оценено до назначения @student, даже если оно помещено после в SELECT.
Это упоминается в документации MySQL следующим образом:
Как правило, вам никогда не следует присваивать значение пользовательской переменной.
и прочитайте значение в том же утверждении. Вы можете получить
ожидаемых результатов, но это не гарантировано. Получатель чего-то
оценка для выражений с участием пользовательских переменных не определена и
может меняться в зависимости от элементов, содержащихся в данном утверждении;
Кроме того, этот порядок не гарантируется одинаковым между
выпуски MySQL Server.
источник: http://dev.mysql.com/doc/refman/5.5/en/user-variables.html
Наконец, я использовал такой трюк, чтобы быть уверенным, что присваиваю @class ПОСЛЕ чтения:
SELECT id_student, id_class, grade,
@student:=CASE WHEN @class <> id_class THEN concat(left(@class:=id_class, 0), 0) ELSE @student+1 END AS rn
FROM
(SELECT @student:= -1) s,
(SELECT @class:= -1) c,
(SELECT *
FROM mytable
ORDER BY id_class, grade desc
) t
Использование функции left () просто используется для установки переменной @class. Затем объедините результат left () (равный NULL), чтобы ожидаемый результат был прозрачным.
Не очень элегантно, но работает!