11

タイプNumericの金額フィールドを持つテーブルがあります。異なる金額値が含まれています。例えば

5.00
7.13
8.86
6.00
1.00

...など

小数点以下がゼロ以外のレコードのみをフェッチする必要があります。つまり、金額に対応するレコードのみを取得します

7.13
8.86

どうすればいいですか?

4

4 に答える 4

17

numeric正確です!

別の回答で主張されているのとは異なり、浮動小数点型numericではなく、SQL 標準で定義されている任意精度型です。保管は正確です。マニュアルを引用します:

数値型は、桁数が非常に多い数値を格納し、正確に計算を実行できます。正確さが要求される金額やその他の数量を格納する場合に特にお勧めします。

答え

あなたの質問の自然な候補は functiontrunc()です。ゼロに向かって切り捨てます- 基本的に整数部分を保持し、残りを破棄します。簡単なテストでは最速ですが、上位候補の間ではその差はわずかです。

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

floor()負の数との違いを生む、次に小さい整数に切り捨てます。

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

integer数字が/bigintに収まる場合は、次のようにキャストすることもできます。

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

上記とは異なり、これは整数に丸められます。

テスト

PostgreSQL 9.1.7 でテスト済み。numeric小数部が 2 桁の10,000 の数字を含む一時テーブルで、約 1% が.00.

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

私の場合の正しい結果: 9890 行。で10ランからのベストタイムEXPLAIN ANALYZE

アーウィン 1

SELECT count(*) FROM t WHERE amount <> trunc(amount) -- 43.129 ミリ秒

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 行でテストします。

デシベル<>ここでフィドル

于 2013-03-08T00:03:13.850 に答える
3

これはうまくいきます:

SELECT *
FROM t
WHERE round(amount,2) != round(amount)

いいえ、浮動小数点数を直接比較することはできません-以下のコードは機能しません(証明としてSQLFiddle ):

SELECT *
FROM t
WHERE amount != round(amount)

amount=の場合1./3 * 3、 のように見えますが1、そうではありません - 比較は失敗します。

于 2013-03-06T07:12:30.590 に答える
3

これは役に立ちますか

SELECT * FROM table WHERE amount - floor(amount) > .00

于 2013-03-06T07:38:37.687 に答える
2
SELECT *
FROM t
WHERE amount != round(amount);
于 2013-03-06T06:47:52.463 に答える