numeric
正確です!
別の回答で主張されているのとは異なり、numeric
浮動小数点型ではありません 、ただし、任意精度タイプ SQL標準で定義されているとおり。ストレージは正確です 。マニュアルを引用します:
数値タイプは、非常に大きな桁数の数値を格納し、正確に計算を実行できます。正確さが要求される場合は、金額やその他の数量を保管することを特にお勧めします。
回答
あなたの質問の自然な候補は、関数 trunc()
です。 。 ゼロに向かって切り捨てます -基本的に整数部分を保持し、残りは破棄します。クイックテストでは最速ですが、上位の候補者の間での違いは重要ではありません。
SELECT * FROM t WHERE amount <> trunc(amount);
floor()
次に小さい整数に切り捨てられます。これにより、負の数との違いが生じます。
SELECT * FROM t WHERE amount <> floor(amount);
数字がinteger
に収まる場合 / bigint
キャストすることもできます:
SELECT * FROM t WHERE amount <> amount::bigint;
このラウンド 上記とは異なり、完全な数になります。
テスト
PostgreSQL9.1.7でテスト済み。 10kのnumeric
の一時テーブル 小数桁が2桁の数字、約1%は.00
。
CREATE TEMP TABLE t(amount) AS
SELECT round((random() * generate_series (1,10000))::numeric, 2);
私の場合の正しい結果:9890行。 EXPLAIN ANALYZE
を使用した10回の実行からのベストタイム 。
アーウィン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
アーウィン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
アーウィン4
SELECT count(*) FROM t WHERE amount <> amount::bigint -- 44.149 ms
アーウィン2
SELECT count(*) FROM t WHERE amount <> floor(amount) -- 44.918 ms
ナンダクマールV
SELECT count(*) FROM t WHERE amount - floor(amount) > .00 -- 46.640 ms
Postgres 12でもほとんどの場合当てはまります (現在、すべてが10倍以上高速であることを除いて)。 10kではなく100k行でテストする:
db<>ここでフィドル