[SP-pm] Maior valor em um campo do tipo varchar no PostgreSQL
Lucas Moraes
lucastiagodemoraes at gmail.com
Thu Jul 25 03:57:44 PDT 2013
Então apesar de ser a mesma tabela, alguns iram ter prefixo e outras não.
Só que o padrão não muda. Se o cliente começar um 1 e ele vai até o fim só
usando inteiros e se ele coloca uma string no início, as demais iram que
ter também. Então eu fiz um select a mais buscando o primeiro valor e
verifico se tem string, se tiver string faço sem cast. Mas eu vou mudar o
código, porque o importante são os números, então vou criar um campo
numeric e vou adicionar o número e deixo o campo codigo como esta mesmo.
Valeu pela dica :)
Em 25 de julho de 2013 07:42, Eden Cardim <eden em insoli.de> escreveu:
> >>>>> "Lucas" == Lucas Moraes <lucastiagodemoraes em gmail.com> writes:
>
> Lucas> Stanislaw era isso mesmo, funcionou: max(codigo::integer)
>
> Funciona… Só que não. Isso vai quebrar horrendamente se você tiver
> valores do tipo 'ALP-001', que você mencionou anteriormente. E se
> todos os valores são garantidamente numéricos, é melhor declarar logo
> o campo como um tipo numérico mesmo.
>
> O motivo pelo qual max(codigo) está retornando 999 é que a ordenação
> está sendo feita por ordem de caracteres, e nos encodings mais
> populares, o caracter '9' tem a maior colação dentre os caracteres
> "alfa-numéricos".
>
> O "correto" nesse caso é declarar um tipo, que vai ensinar ao
> postgresql como se ordenam esses valores (AAA-999 é "maior" ou "menor"
> que ZZZ-000?). Algumas alternativas improvisadas que são mais
> simples/fáceis porém tem algumas desvantagens:
>
> - excluir valores não-numéricos via regex: WHERE codigo ~~ '^\d+$'
> que é extremamente lento e precisa de tratamento separado pros
> valores que tem caracteres não-númericos.
>
> - criar um mapeamento de equivalência num segundo campo e usar esse
> campo pra fazer a ordenação, invés do original. Isso depende da
> garantia manual de integridade do mapeamento.
>
> - quebrar o campo codigo em dois campos, um varchar, que vai conter a
> parte 'ALP', e um numérico, que vai conter a parte '001'
> representada como 1. Na hora de recuperar o valor original, você
> remonta o valor com:
>
> select cod_char || '-' ||
> overlay('000' placing cod_num
> from 3 - length(cod_num::string))
> from tabela order by cod_num desc, cod_char limit 1;
>
> Isso só vai funcionar se a parte numérica tiver a mesma "largura" em
> caracteres na parte numérica, senão você vai precisar de um terceiro
> campo pra armazenar essa informação, etc. Você pode declarar views
> pra fazer as conversões automaticamente. Essa é a abordagem que eu
> recomendo.
>
> Sim, é um problema mais complicado do que parece. Pode chorar e
> espernear a vontade, mas não há uma forma "simples" de resolver isso
> que não deixe pontos de falha grotescos sobrando. Como de costume:
> "não existe almoço gratuito".
>
> --
> Eden Cardim -- Insolide Soluções de TI Ltda.
> +55 11 9 9644 8225
> http://insoli.de
> =begin disclaimer
> Sao Paulo Perl Mongers: http://sao-paulo.pm.org/
> SaoPaulo-pm mailing list: SaoPaulo-pm em pm.org
> L<http://mail.pm.org/mailman/listinfo/saopaulo-pm>
> =end disclaimer
>
-------------- Pr?xima Parte ----------
Um anexo em HTML foi limpo...
URL: <http://mail.pm.org/pipermail/saopaulo-pm/attachments/20130725/d7d2fd1c/attachment-0001.html>
More information about the SaoPaulo-pm
mailing list