PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

Pobierz rekordy, które są niezerowe po przecinku w PostgreSQL

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



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Zoptymalizuj zapytanie z PRZESUNIĘCIEM na dużym stole

  2. dostosuj pager w psql

  3. Wybierz odblokowany wiersz w Postgresql

  4. Czy istnieje limit czasu dla bezczynnych połączeń PostgreSQL?

  5. Projekt bazy danych do tworzenia tabel w locie