numeric
is exact!
In tegenstelling tot een ander antwoord, numeric
is geen type met drijvende komma , maar een willekeurig precisietype zoals gedefinieerd door de SQL-standaard. Opslag is exact . Ik citeer de handleiding:
Het type numeriek kan getallen met een zeer groot aantal cijfers opslaan en exacte berekeningen uitvoeren. Het wordt met name aanbevolen voor het opslaan van geldbedragen en andere hoeveelheden waar nauwkeurigheid vereist is.
Antwoord
De natuurlijke kandidaat voor uw vraag is de functie trunc()
. Het kapt naar nul af - in feite het gehele deel behouden terwijl de rest wordt weggegooid. Snelste in een snelle test, maar het verschil tussen de topkandidaten is niet groot.
SELECT * FROM t WHERE amount <> trunc(amount);
floor()
kapt af tot het eerstvolgende lagere gehele getal, wat een verschil maakt met negatieve getallen:
SELECT * FROM t WHERE amount <> floor(amount);
Als je getallen in integer
passen / bigint
je kunt ook gewoon casten:
SELECT * FROM t WHERE amount <> amount::bigint;
Dit rondt naar volledige getallen, in tegenstelling tot het bovenstaande.
Test
Getest met PostgreSQL 9.1.7. Tijdelijke tabel met 10k numeric
getallen met twee gebroken cijfers, ongeveer 1% heeft .00
.
CREATE TEMP TABLE t(amount) AS
SELECT round((random() * generate_series (1,10000))::numeric, 2);
Correct resultaat in mijn geval:9890 rijen. Beste tijd vanaf 10 runs met 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
Meestal nog steeds waar in Postgres 12 (behalve dat alles nu> 10x sneller is). Test met 100k rijen in plaats van 10k:
db<>viool hier