我有一个带有Numeric类型的数量字段的表。它包含不同的金额值。例如
5.00
7.13
8.86
6.00
1.00
... ETC。
我必须只获取小数点后非零的那些记录。即,仅获取与金额对应的记录
7.13
8.86
我该怎么做?
我有一个带有Numeric类型的数量字段的表。它包含不同的金额值。例如
5.00
7.13
8.86
6.00
1.00
... ETC。
我必须只获取小数点后非零的那些记录。即,仅获取与金额对应的记录
7.13
8.86
我该怎么做?
numeric
是准确的!与另一个答案所声称的不同,numeric
它不是浮点类型,而是SQL 标准定义的任意精度类型。存储准确。我引用手册:
numeric 类型可以存储具有非常多位数的数字并精确地执行计算。特别推荐用于存储货币数量和其他需要精确性的数量。
您问题的自然候选者是 function 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 测试。有 10knumeric
个数字和两个小数位的临时表,大约 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 ms
SELECT count(*) FROM t WHERE amount != round(amount) -- 43.406 ms
欧文 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
欧文 4
SELECT count(*) FROM t WHERE amount <> amount::bigint -- 44.149 ms
欧文 2
SELECT count(*) FROM t WHERE amount <> floor(amount) -- 44.918 ms
SELECT count(*) FROM t WHERE amount - floor(amount) > .00 -- 46.640 ms
在Postgres 12中大多数情况下仍然如此(除了现在一切都快了 > 10 倍)。使用 100k 行而不是 10k 行进行测试:
db<>在这里摆弄
这将起作用:
SELECT *
FROM t
WHERE round(amount,2) != round(amount)
不,您不能直接比较浮点数- 下面的代码不起作用(SQLFiddle作为证明):
SELECT *
FROM t
WHERE amount != round(amount)
如果amount
= 1./3 * 3
,它看起来像1
,但它不是 - 比较将失败。
这有帮助吗
SELECT * FROM table WHERE amount - floor(amount) > .00
SELECT *
FROM t
WHERE amount != round(amount);