PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Recupera i record che sono diversi da zero dopo il punto decimale in PostgreSQL

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