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

har*_*rry 8 sql postgresql types postgresql-8.4

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

5.00
7.13
8.86
6.00
1.00
Run Code Online (Sandbox Code Playgroud)

...等

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

7.13
8.86
Run Code Online (Sandbox Code Playgroud)

我该怎么做?

Erw*_*ter 11

numeric 确切的!

与另一个答案所声称的不同,numeric不是浮点类型,而是SQL标准定义的任意精度类型.存储是准确的.我引用手册:

数字类型可以存储具有大量数字的数字并精确执行计算.特别建议在需要准确性的情况下存储货币金额和其他数量.

回答

您问题的自然候选者是函数trunc().它截断为零.它也是快速测试中最快的.但是,顶级竞争者之间的差异并不大.

SELECT * FROM t WHERE amount <> trunc(amount);
Run Code Online (Sandbox Code Playgroud)

这比floor()仅忽略标志更简单,因此也应该更快.

SELECT * FROM t WHERE amount <> floor(amount);
Run Code Online (Sandbox Code Playgroud)

如果你的数字适合integer/bigint你也可以只是施放:

SELECT * FROM t WHERE amount <> amount::bigint;
Run Code Online (Sandbox Code Playgroud)

测试

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

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

在我的情况下正确的结果:9890行.10次​​奔跑的最佳时间EXPLAIN ANALYZE.

欧文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
Run Code Online (Sandbox Code Playgroud)

欧文3

SELECT count(*) FROM t WHERE amount <> amount::int            -- 43.668 ms
Run Code Online (Sandbox Code Playgroud)

mvp 1

SELECT count(*) FROM t WHERE round(amount,2) != round(amount) -- 44.144 ms
Run Code Online (Sandbox Code Playgroud)

欧文4

SELECT count(*) FROM t WHERE amount <> amount::bigint         -- 44.149 ms
Run Code Online (Sandbox Code Playgroud)

欧文2

SELECT count(*) FROM t WHERE amount <> floor(amount)          -- 44.918 ms
Run Code Online (Sandbox Code Playgroud)

Nandakumar V

SELECT count(*) FROM t WHERE amount - floor(amount) > .00     -- 46.640 ms
Run Code Online (Sandbox Code Playgroud)