我有一个表格,其中包含数字类型的金额字段。它包含不同的金额值。例如
5.00
7.13
8.86
6.00
1.00
......等等。
我只能获取小数点后非零的记录。 即,仅获取与金额相对应的记录
7.13
8.86
我该怎么做?
答案 0 :(得分:10)
numeric
是确切的!与其他答案不同, numeric
为not 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
SELECT count(*) FROM t WHERE amount != round(amount) -- 43.406 ms
Erwin 3
SELECT count(*) FROM t WHERE amount <> amount::int -- 43.668 ms
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
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);