"Normalizar" para classificação
Você poderia use
regexp_replace()
com o padrão '[^a-zA-Z]'
no ORDER BY
cláusula, mas que só reconhece letras ASCII puras. É melhor usar a abreviação de classe '\W'
que reconhece letras não ASCII adicionais em sua localidade, como äüóèß
etc. Ou você poderia improvisar e "normalizar todos os caracteres com elementos diacríticos para sua forma base com a ajuda do unaccent()
função. Considere esta pequena demonstração:SELECT *
, regexp_replace(x, '[^a-zA-Z]', '', 'g')
, regexp_replace(x, '\W', '', 'g')
, regexp_replace(unaccent(x), '\W', '', 'g')
FROM (
SELECT 'XY ÖÜÄöüäĆČćč€ĞğīїıŁłŃńŇňŐőōŘřŠšŞşůŽžż‘´’„“”–—[](),;.:̈� XY'::text AS x) t
->SQLfiddle para Postgres 9.2.
->SQLfiddle para Postgres 9.1.
O código de expressão regular foi atualizado na versão 9.2. Estou assumindo esta é a razão para a manipulação aprimorada em 9.2, onde todos os caracteres de letras no exemplo são correspondidos, enquanto 9.1 corresponde apenas a alguns.
unaccent()
é fornecido pelo módulo adicional unaccent
. Corre:CREATE EXTENSION unaccent;
uma vez por banco de dados para usar (Postgres 9.1+, versões mais antigas usam um técnica diferente ).
localidades / agrupamento
Você deve estar ciente de que o Postgres depende do sistema operacional subjacente para localidades (incluindo agrupamento). A ordem de classificação é regida pela localidade escolhida ou, mais especificamente,
LC_COLLATE
. Mais nesta resposta relacionada:Ordem de classificação de strings (LC_COLLATE e LC_CTYPE)
Existem planos para incorporar suporte de agrupamento diretamente no Postgres , mas isso não está disponível no momento.
Muitas localidades ignoram os caracteres especiais que você descreve para classificar dados de caracteres prontos para uso. Se você tiver uma localidade instalada em seu sistema que forneça a ordem de classificação que você está procurando, você pode usá-la ad-hoc no Postgres 9.1 ou posterior:
SELECT foo FROM bar ORDER BY foo COLLATE "xy_XY"
Para ver quais agrupamentos estão instalados e disponíveis em sua instalação atual do Postgres:
SELECT * FROM pg_collation;
Infelizmente, não é possível definir seu próprio agrupamento personalizado (ainda), a menos que você hackeie o código-fonte.
As regras de agrupamento são geralmente regidas pelas regras de um idioma falado em um país. As listas telefônicas de ordem de classificação estariam, se ainda houvesse listas telefônicas... Seu sistema operacional as fornece.
Por exemplo, no Debian Linux você pode usar:
locale -a
para exibir todas as localidades geradas. E:
dpkg-reconfigure locales
como usuário root (uma forma de várias) para gerar/instalar mais.