0

我正在尝试使用 regexp_like 来查找和删除过于精确的浮点数。

select c from t order by c asc;

返回许多这样的结果:0.0000000012345678

使用 regexp_like 我可以获得两位小数(0.25)的结果:

select * from t where REGEXP_LIKE(c,'^\d+\.\d{2}');

但是,当我尝试两个以上的地方时,我没有得到任何结果:

select * from t where REGEXP_LIKE(c,'^\d+\.\d{3}');
...
select * from t where REGEXP_LIKE(c,'^\d+\.\d{10}');

唯一的附加信息是我正在选择第二个视图的视图,并且我正在搜索的列(c,上面)被指定为 FLOAT。

4

1 回答 1

1

您可以将它们视为数字。您可以将值截断为固定的小数位数:

( TRUNCnumber) 函数返回n1截断到n2位小数。

然后看看是否匹配。例如,要查找小数点后有效数字多于 2 位的任何值:

 select * from t where c != trunc(c, 2);

或查找有效数字超过 10 位的那些:

 select * from t where c != trunc(c, 10);

我用过!=而不是>在你有负值的情况下。

您也可以将其用作删除/更新中的过滤器,或者set如果您想降低精度,则将其用作更新的一部分 - 尽管在这种情况下您可能想要使用round()fo trunc()


当您使用时,regexp_like您正在将浮点值隐式转换为字符串,并作为注释文档:to_char()

如果省略fmt,则n将转换为一个VARCHAR2足够长的值以保存其有效数字。

这意味着 0.25 成为字符串'.25',没有前导零;这甚至与您的第一个模式都不匹配。

*您可以通过使用而不是允许前导零不存在+,例如查找小数点后至少有 10 个有效数字的值:

select * from t where REGEXP_LIKE(c,'^\d*\.\d{10}');

或者正好是10:

select * from t where REGEXP_LIKE(c,'^\d*\.\d{10}$');

ETC。; 但将它们视为数字而不是字符串似乎更简单。

于 2018-12-13T13:53:38.367 回答