PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

Abrufen von Datensätzen, die nach dem Dezimalkomma in PostgreSQL ungleich Null sind

numeric ist genau!

Anders als in einer anderen Antwort behauptet, numeric ist kein Fließkommatyp , aber ein Typ mit beliebiger Genauigkeit wie vom SQL-Standard definiert. Die Speicherung ist exakt . Ich zitiere das Handbuch:

Der Typ numeric kann Zahlen mit sehr vielen Stellen speichern und Berechnungen exakt durchführen. Es empfiehlt sich besonders für die Aufbewahrung von Geldbeträgen und anderen Mengen, bei denen Genauigkeit erforderlich ist.

Antwort

Der natürliche Kandidat für Ihre Frage ist die Funktion trunc() . Es schneidet gegen Null ab - Grundsätzlich den ganzzahligen Teil beibehalten, während der Rest verworfen wird. Schnellster in einem Schnelltest, aber der Unterschied zu den Top-Konkurrenten ist unbedeutend.

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

floor() schneidet auf die nächstniedrigere Ganzzahl ab, was bei negativen Zahlen einen Unterschied macht:

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

Wenn Ihre Zahlen in integer passen / bigint Sie können auch einfach umwandeln:

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

Das rundet auf volle Zahlen, anders als oben.

Test

Getestet mit PostgreSQL 9.1.7. Temporäre Tabelle mit 10k numeric Zahlen mit zwei Nachkommastellen, etwa 1 % haben .00 .

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

Richtiges Ergebnis in meinem Fall:9890 Zeilen. Bestzeit aus 10 Läufen mit 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

mvp1

SELECT count(*) FROM t WHERE round(amount,2) != round(amount) -- 44.144 ms

Erwin4

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

In Postgres 12 größtenteils noch zutreffend (außer dass jetzt alles> 10x schneller ist). Testen Sie mit 100.000 Zeilen statt 10.000:

db<>hier fummeln