Perché ci serve tutto questo — confronto e conversione dei tipi? Immagina di avere nella tabella una stringa "42", e vuoi confrontarla con il numero 42. A prima vista — sembra la stessa cosa. Ma per il database possono essere cose completamente diverse. PostgreSQL non indovinerà automaticamente cosa intendevi. E se non capisci come confronta i valori di tipi diversi, puoi ottenere risultati strani o addirittura un errore.
Stessa cosa per le conversioni. A volte devi trasformare un testo in numero per contare quante cose ci sono. Altre volte, invece, vuoi mostrare un numero come stringa in modo carino. O magari prendere una data e mostrarla come "01.01.2025", perché così è più familiare per l’utente.
Oppure un altro esempio: hai un valore preciso salvato come NUMERIC, ma per i calcoli scientifici ti serve usare FLOAT. In questi casi, senza una conversione esplicita, non vai da nessuna parte.
La buona notizia è che PostgreSQL se la cava alla grande. Ti dà strumenti flessibili e chiari per queste cose. L’importante è sapere come usarli e non aver paura di guardare un po’ sotto il cofano. È proprio quello che faremo ora.
Confronto dei tipi di dati
PostgreSQL cerca di essere smart — se vede che stai confrontando, per esempio, INTEGER e NUMERIC, li porta tranquillamente a un denominatore comune e fa il confronto. Va bene, perché sono entrambi numeri.
Ma se provi a confrontare una stringa con un valore booleano (TEXT e BOOLEAN), il database non capirà cosa vuoi da lui. Questi tipi sono proprio di natura diversa, e PostgreSQL ti darà un errore. Stessa cosa se provi a confrontare la stringa "42" con il numero 42 senza dire esplicitamente che vuoi trasformare quella stringa in numero.
Come si presenta nella pratica? Ecco un esempio che darà errore:
SELECT '42' = 42; -- Errore! Stringa e numero non si confrontano senza conversione
Invece così funziona tutto come deve:
SELECT '42'::INTEGER = 42; -- TRUE
Qui diciamo chiaramente: “Per favore, prima trasforma '42' in numero”. Per questo serve la sintassi ::Tipo, di cui abbiamo già parlato. PostgreSQL apprezza quando parli con lui in modo preciso.
Confronto dei tipi numerici
I tipi numerici (INTEGER, NUMERIC, REAL) di solito sono compatibili tra loro, quindi puoi confrontarli senza troppi problemi:
SELECT 42 = 42.0; -- TRUE
SELECT 42::REAL = 42.0; -- TRUE
SELECT 42.0::NUMERIC = 42; -- TRUE
Ma occhio ai numeri floating point (REAL). Per via della precisione limitata, questi numeri possono comportarsi in modo strano. Per esempio:
SELECT 0.1 + 0.2 = 0.3; -- FALSE
Non è forse il mistero più famoso della programmazione? Qui il confronto restituisce FALSE per via di come i numeri decimali vengono salvati nella memoria del computer.
Confronto dei tipi testuali
Lavorando con tipi testuali puoi confrontare CHAR, VARCHAR e TEXT, perché PostgreSQL li converte automaticamente in tipi compatibili:
SELECT 'Hello' = 'Hello'::TEXT; -- TRUE
SELECT 'World'::CHAR(5) = 'World'::VARCHAR; -- TRUE
Fai attenzione alla lunghezza dei caratteri in CHAR(n): se la stringa è più corta della lunghezza indicata, PostgreSQL la riempie di spazi.
Conversione dei tipi di dati
PostgreSQL offre diversi modi per convertire i tipi di dati. Vediamo i due metodi principali:
Metodo n°1: Conversione esplicita (CAST)
L’operatore CAST ti permette di specificare come convertire un tipo in un altro. Ecco un esempio:
SELECT CAST('42' AS INTEGER); -- Converte la stringa '42' nel numero 42
Questo metodo è particolarmente comodo se vuoi rendere il codice SQL più leggibile.
Metodo n°2: Notazione abbreviata (::)
PostgreSQL offre una sintassi alternativa per la conversione dei tipi — usando ::. È la stessa operazione, ma scritta più corta:
SELECT '42'::INTEGER; -- Uguale a CAST('42' AS INTEGER)
Conversione automatica
In molti casi PostgreSQL converte i dati automaticamente. Per esempio, usando numeri nei campi testuali:
SELECT '42' = 42::TEXT; -- TRUE
Però, affidarsi alla conversione automatica non è sempre sicuro, perché può sorprendere altri sviluppatori. Per esempio, con date e stringhe è meglio usare la conversione esplicita.
Esempi di conversione tra diversi tipi di dati
Conversione di numeri in testo
A volte serve convertire numeri in testo (tipo per creare messaggi):
SELECT 42::TEXT; -- Converte il numero 42 nella stringa '42'
SELECT 3.14::TEXT; -- Converte il numero 3.14 nella stringa '3.14'
Conversione di testo in numeri
Se la stringa contiene un numero valido, puoi convertirla in tipo numerico:
SELECT '123'::INTEGER; -- Converte la stringa '123' nel numero 123
SELECT '3.14'::FLOAT; -- Converte la stringa '3.14' nel numero 3.14
Ma cosa succede se il testo non si può convertire? Per esempio:
SELECT 'Hello'::INTEGER; -- Errore: impossibile convertire 'Hello' in numero
Per evitare questi errori, puoi usare la funzione TRY_CAST() (da PostgreSQL 14 in poi) o controllare i dati prima.
Conversione di date in testo e viceversa
Per convertire le date puoi usare le funzioni TO_CHAR() e TO_DATE():
SELECT TO_CHAR(CURRENT_DATE, 'YYYY-MM-DD'); -- Converte la data in stringa
SELECT TO_DATE('2023-10-25', 'YYYY-MM-DD'); -- Converte la stringa in data
Conversione tra BOOLEAN e testo
Il tipo logico BOOLEAN si può anche convertire in stringa:
SELECT TRUE::TEXT; -- 'true'
SELECT FALSE::TEXT; -- 'false'
O viceversa:
SELECT 'true'::BOOLEAN; -- TRUE
SELECT 'false'::BOOLEAN; -- FALSE
Attenzione: stringhe come 'yes' o 'no' non verranno convertite automaticamente.
Pratica: tutto su esempi reali
Creiamo una tabella che mostra l’uso di diversi tipi di dati:
| id | number_as_text - TEXT | number_as_integer - INTEGER | date_as_text - TEXT | actual_date - DATE |
|---|---|---|---|---|
| 1 | 42 | 42 | 2023-10-25 | 2023-10-25 |
| 2 | 3.14 | NULL | 2023-10-24 | NULL |
| 3 | Hello | 123 | NULL | NULL |
Ora facciamo delle operazioni di conversione:
-- Conversione di testo in numero
SELECT number_as_text::INTEGER FROM data_types_demo WHERE number_as_text = '42';
-- Conversione di data in testo
SELECT TO_CHAR(actual_date, 'DD/MM/YYYY') FROM data_types_demo;
-- Conversione di stringa in data
SELECT TO_DATE(date_as_text, 'YYYY-MM-DD') FROM data_types_demo;
Errori tipici nella conversione dei dati
Gli errori più comuni includono:
- Tentativi di convertire dati che non rispettano il formato atteso (per esempio, la stringa
'Hello'inINTEGER). - Problemi di arrotondamento e precisione lavorando con numeri floating point.
- Uso scorretto dei formati nella conversione delle date.
Per evitare errori si consiglia di:
- Controllare sempre i dati prima della conversione.
- Usare funzioni di gestione degli errori (
TRY_CASToCASE). - Specificare il formato in modo esplicito quando converti le date.
-- Controllo dei dati prima della conversione
SELECT
CASE
WHEN number_as_text ~ '^\d+$' THEN number_as_text::INTEGER
ELSE NULL
END AS safe_integer
FROM data_types_demo;
Usa questo approccio per proteggere le tue query da situazioni impreviste!
A questo punto hai le basi per confrontare e convertire i tipi di dati in PostgreSQL. Ora serve solo pratica, pratica e ancora pratica. Ci vediamo alle prossime lezioni!
GO TO FULL VERSION