numeric
es exacto!
A diferencia de lo que afirma otra respuesta, numeric
no es un tipo de punto flotante , pero un tipo de precisión arbitraria como lo define el estándar SQL. El almacenamiento es exacto . Cito el manual:
El tipo numérico puede almacenar números con una gran cantidad de dígitos y realizar cálculos con precisión. Está especialmente recomendado para el almacenamiento de cantidades monetarias y otras cantidades donde se requiera exactitud.
Respuesta
El candidato natural para su pregunta es la función trunc()
. Se trunca hacia cero - básicamente manteniendo la parte entera y descartando el resto. Más rápido en una prueba rápida, pero la diferencia es insignificante entre los principales contendientes.
SELECT * FROM t WHERE amount <> trunc(amount);
floor()
se trunca al siguiente entero inferior, lo que hace una diferencia con los números negativos:
SELECT * FROM t WHERE amount <> floor(amount);
Si sus números caben en integer
/ bigint
también puedes lanzar:
SELECT * FROM t WHERE amount <> amount::bigint;
Esta ronda a números completos, a diferencia de lo anterior.
Prueba
Probado con PostgreSQL 9.1.7. Tabla temporal con 10k numeric
números con dos dígitos fraccionarios, alrededor del 1% tienen .00
.
CREATE TEMP TABLE t(amount) AS
SELECT round((random() * generate_series (1,10000))::numeric, 2);
Resultado correcto en mi caso:9890 filas. Mejor tiempo de 10 carreras 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
jugador más valioso 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
Mayormente sigue siendo cierto en Postgres 12 (excepto que ahora todo es> 10 veces más rápido). Prueba con 100k filas en lugar de 10k:
db<>violín aquí