numeric
jest dokładne!
W przeciwieństwie do roszczenia przez inną odpowiedź, numeric
nie jest typem zmiennoprzecinkowym , ale dowolny typ precyzji zgodnie z definicją w standardzie SQL. Pamięć jest dokładna . Cytuję instrukcję:
Typ numeryczny może przechowywać liczby o bardzo dużej liczbie cyfr i dokładnie wykonywać obliczenia. Jest szczególnie polecany do przechowywania kwot pieniężnych i innych ilości, w których wymagana jest dokładność.
Odpowiedź
Naturalnym kandydatem na Twoje pytanie jest funkcja trunc()
. Obcina do zera - zasadniczo zachowując część całkowitą, odrzucając resztę. Najszybszy w szybkim teście, ale różnica między najlepszymi rywalami jest nieistotna.
SELECT * FROM t WHERE amount <> trunc(amount);
floor()
obcina do następnej niższej liczby całkowitej, co ma znaczenie w przypadku liczb ujemnych:
SELECT * FROM t WHERE amount <> floor(amount);
Jeśli Twoje liczby mieszczą się w integer
/ bigint
możesz też po prostu przesłać:
SELECT * FROM t WHERE amount <> amount::bigint;
Ta runda do pełnych liczb, w przeciwieństwie do powyższego.
Test
Testowane z PostgreSQL 9.1.7. Tabela tymczasowa z 10k numeric
liczby z dwiema cyframi ułamkowymi, około 1% ma .00
.
CREATE TEMP TABLE t(amount) AS
SELECT round((random() * generate_series (1,10000))::numeric, 2);
Prawidłowy wynik w moim przypadku:9890 wierszy. Najlepszy czas z 10 biegów z 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
Erwina 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
Erwina 4
SELECT count(*) FROM t WHERE amount <> amount::bigint -- 44.149 ms
Erwina 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
W większości nadal prawdziwe w Postgres 12 (poza tym, że teraz wszystko jest> 10x szybsze). Przetestuj ze 100 tys. wierszy zamiast 10 tys.:
db<>graj tutaj