web-dev-qa-db-fra.com

Extraire des nombres d'un champ dans PostgreSQL

J'ai un tableau avec une colonne po_number de type varchar dans Postgres 8.4. Il stocke des valeurs alphanumériques avec quelques caractères spéciaux. Je veux ignorer les caractères [/alpha/?/$/encoding/.] et vérifiez si la colonne contient un nombre ou non. Si c'est un nombre, alors il doit transtyper en nombre ou bien passer null, comme mon champ de sortie po_number_new est un champ numérique.

Voici l'exemple:

example

SQL Fiddle.

J'ai fatigué cette déclaration:

select 
(case when  regexp_replace(po_number,'[^\w],.-+\?/','') then po_number::numeric
else null
end) as po_number_new from test

Mais j'ai eu une erreur pour la distribution explicite:

error

12
user1538020

Simplement:

SELECT NULLIF(regexp_replace(po_number, '\D','','g'), '')::numeric AS result
FROM   tbl;

\D étant le raccourci de classe pour "pas un chiffre".
Et vous avez besoin du 4ème paramètre 'g' (pour "globalement") pour remplacer toutes les occurrences .
Détails dans le manuel.

Mais pourquoi Postgres 8.4? Pensez à passer à une version moderne.

Considérez les pièges des versions obsolètes:

26
Erwin Brandstetter

Je pense que vous voulez quelque chose comme ça:

select (case when regexp_replace(po_number, '[^\w],.-+\?/', '') ~ '^[0-9]+$'
             then regexp_replace(po_number, '[^\w],.-+\?/', '')::numeric
        end) as po_number_new 
from test;

Autrement dit, vous devez effectuer la conversion sur la chaîne après remplacement.

Remarque: Cela suppose que le "nombre" n'est qu'une chaîne de chiffres.

2
Gordon Linoff

La logique que j'utiliserais pour déterminer si le po_number champ contient des chiffres numériques est que sa longueur doit diminuer lorsque vous essayez de supprimer des chiffres numériques.

Si oui, tous les chiffres non numériques ([^\d]) doit être supprimé du po_number colonne. Sinon, NULL doit être retourné.

select case when char_length(regexp_replace(po_number, '\d', '', 'g')) < char_length(po_number)
            then regexp_replace(po_number, '[^0-9]', '', 'g')
            else null
       end as po_number_new
from test
1
Tim Biegeleisen