在PostgreSQL中获取小数点后非零的记录

时间:2013-03-06 06:39:03

标签: sql postgresql types postgresql-8.4

我有一个表格,其中包含数字类型的金额字段。它包含不同的金额值。例如

5.00
7.13
8.86
6.00
1.00

......等等。

我只能获取小数点后非零的记录。 即,仅获取与金额相对应的记录

7.13
8.86

我该怎么做?

4 个答案:

答案 0 :(得分:10)

numeric是确切的!

与其他答案不同, numericnot a floating-point type ,但是arbitrary precision type由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;

测试

使用PostgreSQL 9.1.7进行测试。带有10k numeric个数字和两个小数位的临时表,大约1%有.00

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

在我的情况下纠正结果:9890行。使用EXPLAIN ANALYZE进行10次运行的最佳时间。

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

mvp 1

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

Erwin 4

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

答案 1 :(得分:3)

这将有效:

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

不,你不能直接比较浮点数 - 下面的代码不起作用(SQLFiddle作为证据):

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

如果amount = 1./3 * 3,它看起来像是1,但它不是 - 比较会失败。

答案 2 :(得分:3)

这会有帮助吗

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

答案 3 :(得分:2)

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