sql >> Base de Datos >  >> RDS >> PostgreSQL

Obtener registros que no sean cero después del punto decimal en PostgreSQL

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í