MySQL: Ordenando campos VARCHAR como se fossem INTEGER

Publicado por Marcos Dell Antonio em 05/12/2006 | .NET, Cotidiano, Delphi

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é +.

7 comentários

  1. 1
    Dimas // January 27th, 2007 at 10:50 pm

    Cara. Muito obrigado! Me ajudou d+!

  2. 2
    elton nunes // February 5th, 2007 at 11:40 am

    ..e para o Firebird ou interbase funciona? pois estou tentando e nada…
    se tiver uma solucao agradeco

  3. 3
    Mauricio // October 15th, 2007 at 4:09 pm

    como posso faser um script em php e mysql, para faser um cadastramento

    com login e senha ?/

  4. 4
    Ivan // December 30th, 2007 at 10:14 pm

    Muito bom, simples e objetivo !

  5. 5
    Djulian // March 26th, 2008 at 11:27 am

    Muito bom, tava precisando disso :)

  6. 6
    px // August 20th, 2008 at 12:13 pm

    vlw.. muito bom.. ajudou muito.

  7. 7
    Wilson // May 20th, 2009 at 9:58 am

    Bom dia, por favor, você pode explicar com mais detalhes como isso funciona?
    Valeu, obrigado.

Deixe o seu comentário

Anúncios

Anúncio provido pelo BuscaPé