Ícone do site Linha de Comando

Como ordenar valores M1/2026 corretamente no MySQL usando ORDER BY

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.

Sair da versão mobile