Триггеры не могут этого сделать
За исключением DDL, ваш подход на основе триггера имеет несколько трудностей.Во-первых, вы хотите изменить саму таблицу, которая была обновлена, и это не разрешено в MySQL 5 .
Во-вторых, вам действительно нужен триггер уровня оператора, а не FOR EACH ROW - нетнужно пересортировать всю таблицу для каждой затронутой строки - но это не поддерживается в MySQL 5 .
Динамически вычислять "rating"
Так ... это так?достаточно просто вычислить rating
динамически, используя обходной путь MySQL ROW_NUMBER () ?
-- ALTER TABLE ft_ttd DROP COLUMN rating; -- if you like
SELECT id,
num,
@i := @i + 1 AS rating
FROM ft_ttd
CROSS JOIN (SELECT @i := 0 AS zero) d
ORDER BY num DESC;
К сожалению, вы не можете обернуть этот SELECT в VIEW (так как представление «Оператор SELECT не может ссылаться на системные или пользовательские переменные» ).Однако вы можете скрыть это в выбираемой хранимой процедуре:
CREATE PROCEDURE sp_ranked_ft_ttd () BEGIN
SELECT id, num, @i := @i + 1 AS rating
FROM ft_ttd CROSS JOIN (SELECT @i := 0 AS zero) d
ORDER BY num DESC
END
Или ОБНОВЛЕНИЕ, если вы должны
В качестве ключа, если вы должны хранить rating
в таблице, а не вычислять ее, вы можете запустить это ОБНОВЛЕНИЕ по мере необходимости:
UPDATE t
CROSS JOIN ( SELECT id, @i := @i + 1 AS new_rating
FROM ft_ttd
CROSS JOIN (SELECT @i := 0 AS zero) d
ORDER BY num DESC
) ranked
ON ft_ttd.id = ranked.id SET ft_ttd.rating = ranked.new_rating;
Теперь проинструктируйте ваш клиентский код игнорировать строки, где rating IS NULL
- они еще не ранжированы.Лучше создайте ВИД, который сделает это за вас.
Продвигаясь дальше, вы, вероятно, можете регулярно ОБНОВЛЯТЬ через СОЗДАТЬ СОБЫТИЕ .