typecast string na integer - Postgres

123

Importuję dane z tabeli, która ma surowe kanały w Varchar, muszę zaimportować kolumnę w varchar do kolumny ciągów. Próbowałem użyć, <column_name>::integerjak również, to_number(<column_name>,'9999999')ale otrzymuję błędy, ponieważ jest kilka pustych pól, muszę je pobrać jako puste lub zerowe do nowej tabeli.

Uprzejmie daj mi znać, jeśli istnieje funkcja dla tego samego.

Vijay DJ
źródło
5
Czy możesz pokazać nam komunikat o błędzie? To by pomogło
Frank Heikens

Odpowiedzi:

126

Dzikie przypuszczenie: jeśli wartość jest pustym ciągiem, możesz użyć NULLIF, aby zastąpić ją wartością NULL:

SELECT
    NULLIF(your_value, '')::int
Frank Heikens
źródło
56

Możesz nawet pójść dalej i ograniczyć na tym zlewającym się polu, na przykład: -

SELECT CAST(coalesce(<column>, '0') AS integer) as new_field
from <table>
where CAST(coalesce(<column>, '0') AS integer) >= 10; 
tatty
źródło
28

Jeśli chcesz traktować puste kolumny jako NULLs, spróbuj tego:

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

Z drugiej strony, jeśli masz NULLwartości, których musisz unikać, spróbuj:

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

Zgadzam się, komunikat o błędzie bardzo by pomógł.

vyegorov
źródło
25

Jedynym sposobem, w jaki mogę nie mieć błędu z powodu NULL, znaków specjalnych lub pustego ciągu, jest zrobienie tego:

SELECT REGEXP_REPLACE(COALESCE(<column>::character varying, '0'), '[^0-9]*' ,'0')::integer FROM table
Charles Hamel
źródło
2
Dla mnie (9.6.2) to była jedyna rzecz, która działała, wszystkie inne odpowiedzi zawiodły.
Jasper de Vries
2
Nie mógłbyś dodać WHERE <column> != NULL?
Matthieu
14

Nie jestem w stanie skomentować (zbyt mała reputacja? Jestem całkiem nowy) pod postem Lukasa.

Na mojej konfiguracji PG to_number(NULL)nie działa, więc moim rozwiązaniem byłoby:

SELECT CASE WHEN column = NULL THEN NULL ELSE column :: Integer END
FROM table
niko
źródło
1
To powinno działać, ale powinno być dokładnym odpowiednikiem mniej szczegółowego NULLIF()podejścia. Standard faktycznie definiuje NULLIF jako formę predykatu CASE.
kgrittn
13

Jeśli wartość zawiera znaki nieliczbowe, możesz przekonwertować wartość na liczbę całkowitą w następujący sposób:

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

Operator CASE sprawdza <kolumnę>, jeśli pasuje do wzorca liczby całkowitej, konwertuje stawkę na liczbę całkowitą, w przeciwnym razie zwraca 0

Igor Ostrovsky
źródło
1

możesz użyć tego zapytania

SUM(NULLIF(conversion_units, '')::numeric)
Abdul Quadir
źródło
1

Powszechny problem

Naiwnie typ rzutujący dowolny ciąg na liczbę całkowitą, taką jak ta

SELECT ''::integer

Często prowadzi do słynnego błędu:

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

Problem

PostgreSQL nie ma predefiniowanej funkcji do bezpiecznego rzutowania dowolnego ciągu znaków na liczbę całkowitą.

Rozwiązanie

Utwórz funkcję zdefiniowaną przez użytkownika zainspirowaną funkcją intval () 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;

Stosowanie

/* 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
źródło