numeric
è esatto!
A differenza di un'altra risposta, numeric
non è un tipo a virgola mobile , ma un tipo di precisione arbitraria come definito dallo standard SQL. Lo spazio di archiviazione è esatto . Cito il manuale:
Il tipo numerico può memorizzare numeri con un numero molto elevato di cifre ed eseguire calcoli esattamente. È particolarmente consigliato per la conservazione di importi monetari e altre quantità in cui è richiesta l'esattezza.
Risposta
Il candidato naturale per la tua domanda è la funzione trunc()
. Tronca verso lo zero - in pratica mantenendo la parte intera scartando il resto. Il più veloce in un test veloce, ma la differenza è insignificante tra i migliori contendenti.
SELECT * FROM t WHERE amount <> trunc(amount);
floor()
tronca al numero intero inferiore successivo, il che fa la differenza con i numeri negativi:
SELECT * FROM t WHERE amount <> floor(amount);
Se i tuoi numeri rientrano in integer
/ bigint
puoi anche solo trasmettere:
SELECT * FROM t WHERE amount <> amount::bigint;
Questo giro a numeri interi, a differenza di quanto sopra.
Prova
Testato con PostgreSQL 9.1.7. Tabella temporanea con 10k numeric
numeri con due cifre frazionarie, circa l'1% ha .00
.
CREATE TEMP TABLE t(amount) AS
SELECT round((random() * generate_series (1,10000))::numeric, 2);
Risultato corretto nel mio caso:9890 righe. Miglior tempo da 10 corse con EXPLAIN ANALYZE
.
Erwin 1
SELECT count(*) FROM t WHERE amount <> trunc(amount) -- 43.129 ms
mvp 2 / qqx
SELECT count(*) FROM t WHERE amount != round(amount) -- 43.406 ms
Erwin 3
SELECT count(*) FROM t WHERE amount <> amount::int -- 43.668 ms
mvp 1
SELECT count(*) FROM t WHERE round(amount,2) != round(amount) -- 44.144 ms
Erwin 4
SELECT count(*) FROM t WHERE amount <> amount::bigint -- 44.149 ms
Erwin 2
SELECT count(*) FROM t WHERE amount <> floor(amount) -- 44.918 ms
Nandakumar V
SELECT count(*) FROM t WHERE amount - floor(amount) > .00 -- 46.640 ms
Per lo più ancora vero in Postgres 12 (tranne che ora è tutto> 10 volte più veloce). Prova con 100.000 righe anziché 10.000:
db<>gioca qui