transtyper la chaîne en entier - Postgres

123

J'importe des données à partir d'une table qui a des flux bruts dans Varchar, j'ai besoin d'importer une colonne dans varchar dans une colonne de chaîne. J'ai essayé d'utiliser <column_name>::integeraussi bien que to_number(<column_name>,'9999999')mais j'obtiens des erreurs, car il y a quelques champs vides, je dois les récupérer comme vides ou nuls dans la nouvelle table.

Veuillez me faire savoir s'il existe une fonction pour le même.

Vijay DJ
la source
5
Pouvez-vous nous montrer le message d'erreur? Cela aiderait
Frank Heikens

Réponses:

126

Wild guess: Si votre valeur est une chaîne vide, vous pouvez utiliser NULLIF pour la remplacer par NULL:

SELECT
    NULLIF(your_value, '')::int
Frank Heikens
la source
56

Vous pouvez même aller plus loin et restreindre ce champ fusionné comme par exemple: -

SELECT CAST(coalesce(<column>, '0') AS integer) as new_field
from <table>
where CAST(coalesce(<column>, '0') AS integer) >= 10; 
fatigué
la source
28

Si vous devez traiter les colonnes vides comme des NULLs, essayez ceci:

SELECT CAST(nullif(<column>, '') AS integer);

D'un autre côté, si vous avez des NULLvaleurs à éviter, essayez:

SELECT CAST(coalesce(<column>, '0') AS integer);

Je suis d'accord, un message d'erreur aiderait beaucoup.

vyegorov
la source
25

La seule façon de réussir à ne pas avoir d'erreur à cause de NULL, de caractères spéciaux ou d'une chaîne vide est de faire ceci:

SELECT REGEXP_REPLACE(COALESCE(<column>::character varying, '0'), '[^0-9]*' ,'0')::integer FROM table
Charles Hamel
la source
2
Pour moi (9.6.2) c'était la seule chose qui fonctionnait, toutes les autres réponses ont échoué.
Jasper de Vries
2
Ne pourriez-vous pas ajouter un WHERE <column> != NULL?
Matthieu
14

Je ne suis pas en mesure de commenter (trop peu de réputation? Je suis assez nouveau) sur le post de Lukas.

Sur ma configuration PG to_number(NULL)ne fonctionne pas, donc ma solution serait:

SELECT CASE WHEN column = NULL THEN NULL ELSE column :: Integer END
FROM table
niko
la source
1
Cela devrait fonctionner, mais cela devrait être un équivalent exact de l' NULLIF()approche moins verbeuse . La norme définit en fait NULLIF comme une forme du prédicat CASE.
kgrittn
13

Si la valeur contient des caractères non numériques, vous pouvez convertir la valeur en entier comme suit:

SELECT CASE WHEN <column>~E'^\\d+$' THEN CAST (<column> AS INTEGER) ELSE 0 END FROM table;

L'opérateur CASE vérifie la <colonne>, s'il correspond au modèle entier, il convertit le taux en entier, sinon il retourne 0

Igor Ostrovsky
la source
1

vous pouvez utiliser cette requête

SUM(NULLIF(conversion_units, '')::numeric)
Abdul Quadir
la source
1

Problème courant

Tapez naïvement en convertissant n'importe quelle chaîne en un entier comme ceci

SELECT ''::integer

Résultat souvent la fameuse erreur:

Query failed: ERROR: invalid input syntax for integer: ""

Problème

PostgreSQL n'a pas de fonction prédéfinie pour convertir en toute sécurité n'importe quelle chaîne en un entier.

Solution

Créez une fonction définie par l'utilisateur inspirée de la fonction intval () de PHP .

CREATE FUNCTION intval(character varying) RETURNS integer AS $$

SELECT
CASE
    WHEN length(btrim(regexp_replace($1, '[^0-9]', '','g')))>0 THEN btrim(regexp_replace($1, '[^0-9]', '','g'))::integer
    ELSE 0
END AS intval;

$$
LANGUAGE SQL
IMMUTABLE
RETURNS NULL ON NULL INPUT;

Usage

/* Example 1 */
SELECT intval('9000');
-- output: 9000

/* Example 2 */
SELECT intval('9gag');
-- output: 9

/* Example 3 */
SELECT intval('the quick brown fox jumps over the lazy dog');
-- output: 0
Abel Callejo
la source