Ao armazenar valores como M1/2026 em uma coluna VARCHAR no MySQL, a ordenação padrão será alfabética. Isso gera resultados incorretos quando precisamos ordenar por ano e módulo.
O Problema
Considere a seguinte estrutura:
CREATE TABLE periodos (
id INT AUTO_INCREMENT PRIMARY KEY,
periodo VARCHAR(10) NOT NULL
);
Inserindo dados:
INSERT INTO periodos (periodo) VALUES
('M2/2026'),
('M1/2024'),
('M4/2025'),
('M3/2025'),
('M1/2026'),
('M2/2025'),
('M1/2025');
Se executarmos:
SELECT * FROM periodos
ORDER BY periodo DESC;
A ordenação será apenas textual, não cronológica.
O resultado esperado é:
M2/2026 M1/2026 M4/2025 M3/2025 M2/2025 M1/2025 M1/2024
A Solução
Precisamos separar o ano do módulo e ordenar individualmente.
SELECT *
FROM periodos
ORDER BY
CAST(SUBSTRING_INDEX(periodo, '/', -1) AS UNSIGNED) DESC,
CAST(REPLACE(SUBSTRING_INDEX(periodo, '/', 1), 'M', '') AS UNSIGNED) DESC;
Explicação técnica
SUBSTRING_INDEX(periodo, ‘/’, -1)
Extrai o ano (ex: 2026).
SUBSTRING_INDEX(periodo, ‘/’, 1)
Extrai o módulo (ex: M2).
REPLACE(…, ‘M’, ”)
Remove o prefixo da letra.
CAST(… AS UNSIGNED)
Converte para número para permitir ordenação correta.
Boa prática recomendada
Se possível, evite armazenar dados compostos em uma única coluna.
CREATE TABLE periodos (
id INT AUTO_INCREMENT PRIMARY KEY,
modulo INT,
ano INT
);
Assim a ordenação fica simples e performática:
SELECT *
FROM periodos
ORDER BY ano DESC, modulo DESC;
Conclusão
Ordenação baseada em string não resolve cenários onde existe composição de dados. Sempre que precisar ordenar partes específicas de um valor VARCHAR, extraia e converta os trechos antes de aplicar o ORDER BY.