PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

Buscar registros que não são zero após o ponto decimal no PostgreSQL

numeric é exato!


Ao contrário do reivindicado por outra resposta, numeric não é um tipo de ponto flutuante , mas um tipo de precisão arbitrária conforme definido pelo padrão SQL. O armazenamento é exato . Cito o manual:

O tipo numeric pode armazenar números com um número muito grande de dígitos e realizar cálculos com exatidão. É especialmente recomendado para armazenar valores monetários e outras quantidades onde a exatidão é necessária.

Resposta


O candidato natural para sua pergunta é a função trunc() . Ele trunca em direção a zero - basicamente mantendo a parte inteira enquanto descarta o resto. Mais rápido em um teste rápido, mas a diferença é insignificante entre os principais concorrentes.
SELECT * FROM t WHERE amount <> trunc(amount);

floor() trunca para o próximo inteiro inferior, o que faz diferença com números negativos:
SELECT * FROM t WHERE amount <> floor(amount);

Se seus números se encaixam em integer / bigint você também pode simplesmente lançar:
SELECT * FROM t WHERE amount <> amount::bigint;

Esta rodadas para números completos, ao contrário do acima.

Teste


Testado com PostgreSQL 9.1.7. Tabela temporária com 10k numeric números com dois dígitos fracionários, cerca de 1% tem .00 .
CREATE TEMP TABLE t(amount) AS
SELECT round((random() * generate_series (1,10000))::numeric, 2);

Resultado correto no meu caso:9890 linhas. Melhor tempo de 10 execuções com 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

Principalmente ainda é verdade no Postgres 12 (exceto que tudo é> 10x mais rápido agora). Teste com 100 mil linhas em vez de 10 mil:

db<>mexa aqui