Ps: Este post trata da ordenação de campos VARCHAR como se fossem INTEGER utilizando o banco MySQL 3.2.9. Provavelmente a solução apresentada é compatível com as versões mais novas.
É muito comum o uso de campos VARCHAR para armazenar valores inteiros e alfanuméricos. No entanto, um grande problema é como ordenar esse tipo de campo como se fosse INTEGER.
No exemplo deste post, vou usar a seguinte tabela:
1 CREATE TABLE teste
2 (
3 codigo VARCHAR(20) NOT NULL,
4 descricao VARCHAR(50) NOT NULL,
5 PRIMARY KEY(codigo)
6 )
Veja que a chave primária (campo “codigo”) é do tipo VARCHAR. Para fazer os testes, usarei os seguintes registros:
1 INSERT INTO teste VALUES ('1', 'Teste 1');
2 INSERT INTO teste VALUES ('2', 'Teste 2');
3 INSERT INTO teste VALUES ('3', 'Teste 3');
4 INSERT INTO teste VALUES ('4', 'Teste 4');
5 INSERT INTO teste VALUES ('5', 'Teste 5');
6 INSERT INTO teste VALUES ('6', 'Teste 6');
7 INSERT INTO teste VALUES ('7', 'Teste 7');
8 INSERT INTO teste VALUES ('8', 'Teste 8');
9 INSERT INTO teste VALUES ('9', 'Teste 9');
10 INSERT INTO teste VALUES ('10', 'Teste 10');
11 INSERT INTO teste VALUES ('11', 'Teste 11');
12 INSERT INTO teste VALUES ('12', 'Teste 12');
Após populada a tabela, o desafio é fazer um SELECT que retorne os registros ordenados pelo campo “codigo”. O comando SQL mais óbvio para isso é:
1 SELECT * FROM teste ORDER BY codigo;
No entanto, ao executar este SQL o resultado apresentado é este:
Veja que a ordem retornada não é a esperada, ou seja, o registro 10, por exemplo, vem logo após o 1, quando deveria vir após o 9. Isso acontece pois o banco de dados está interpretando o campo “codigo” como VARCHAR.
Uma maneira muito comum para resolver este problema é cadastrar todos os registros prefixados com vários zeros, exemplo: 00001, 00002, 00010, etc. Desta forma, o SQL acima funciona.
No entanto, forçar o usuário a cadastrar suas informações utilizando um prefixo não é nada elegante quando existe outra solução muito mais simples. Veja o comando SQL que resolve este problema:
1 SELECT * FROM teste
2 ORDER BY
3 CONCAT(REPEAT("0", 20 - LENGTH(codigo)), codigo);
O resultado apresentado é este:
As funções
CONCAT,
REPEAT e
LENGTH fazem um tratamento no campo código de tal forma que o banco passa a ordenar considerando um prefixo (neste caso vários zeros).
Para mais informações, nada melhor do que a documentação oficial.
É isso aí! Até +.