PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Récupérer les enregistrements non nuls après la virgule décimale dans PostgreSQL

numeric est exact !

Contrairement à une autre réponse, numeric n'est pas un type à virgule flottante , mais un type de précision arbitraire tel que défini par la norme SQL. Le stockage est exact . Je cite le manuel :

Le type numeric permet de stocker des nombres avec un très grand nombre de chiffres et d'effectuer des calculs avec précision. Il est particulièrement recommandé de stocker des montants monétaires et d'autres quantités lorsque l'exactitude est requise.

Répondre

Le candidat naturel pour votre question est la fonction trunc() . Il tronque vers zéro - en gardant essentiellement la partie entière tout en supprimant le reste. Le plus rapide dans un test rapide, mais la différence est insignifiante parmi les meilleurs prétendants.

SELECT * FROM t WHERE amount <> trunc(amount);

floor() tronque à l'entier inférieur suivant, ce qui fait une différence avec les nombres négatifs :

SELECT * FROM t WHERE amount <> floor(amount);

Si vos nombres correspondent à integer / bigint vous pouvez aussi simplement caster :

SELECT * FROM t WHERE amount <> amount::bigint;

Cela tourne en nombres entiers, contrairement à ce qui précède.

Tester

Testé avec PostgreSQL 9.1.7. Table temporaire avec 10k numeric nombres avec deux chiffres fractionnaires, environ 1 % ont .00 .

CREATE TEMP TABLE t(amount) AS
SELECT round((random() * generate_series (1,10000))::numeric, 2);

Résultat correct dans mon cas :9890 lignes. Meilleur temps sur 10 runs avec 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

Vice-président Nandakumar

SELECT count(*) FROM t WHERE amount - floor(amount) > .00     -- 46.640 ms

Généralement toujours vrai dans Postgres 12 (sauf que tout est> 10 fois plus rapide maintenant). Testez avec 100 000 lignes au lieu de 10 000 :

db<>jouez ici