【问题标题】:Oracle floating point comparisonOracle 浮点数比较
【发布时间】:2021-07-10 00:42:28
【问题描述】:

我有一个非常奇怪的情况,数字很大。 查询

select edge_id from edges where rownum = 1 

返回 2.57775300147101E21

可以建议查询

select * from edges where edge_id = 2.57775300147101E21

select * from edges where edge_id = 2577753001471010000000

将返回一行。

但它返回“未选择行”...

让我们继续:

select to_char(edge_id) from edges where rownum = 1 

返回 2577753001471010316917

这对我来说是意外的行为。 这种情况下如何查询表?

【问题讨论】:

    标签: oracle comparison precision point floating


    【解决方案1】:

    2.57775300147101E21 的显示值就是 - 显示 值。实际值为 2577753001471010316917,如您的 TO_CHAR(... 查询中所示,因此要检索此行(可能还有其他行),您需要使用正确的值:

    SELECT *
      FROM EDGES
      WHERE EDGE_ID = 2577753001471010316917
    

    或者您可以使用科学计数法中的正确值:

    SELECT *
      FROM EDGES
      WHERE EDGE_ID = 2.577753001471010316917E21
    

    或者您可以进行范围查询,例如:

    SELECT *
      FROM EDGES
      WHERE EDGE_ID BETWEEN 2.5E21
                        AND 2.6E21
    

    您用来查询数据库的任何工具显然都使用科学记数法显示“大”值。但是 2577753001471010316917 的值是您需要用来检索所需行的正确值。

    db<>fiddle here

    【讨论】:

      【解决方案2】:

      第一个答案是绝对正确的 - 只需将数字格式设置更改为 TME(科学记数法)或 TM9。 sql*plus 示例:格式 TM9:

      SQL> show numf
      numformat ""
      SQL> select 2577753001471010316917 x from dual;
      
               X
      ----------
      2.5778E+21
      
      SQL> set numf tm9
      SQL> select 2577753001471010316917 x from dual;
      
                                                                     X
      ----------------------------------------------------------------
      2577753001471010316917
      
      SQL> set numf tme
      SQL> select 2577753001471010316917 x from dual;
      
                                                                     X
      ----------------------------------------------------------------
      2.577753001471010316917E+21
      
      

      【讨论】:

      • 我不懂你。我只想查询 2.57775300147101E21 精确。我怎么知道 2.57775300147101E21 等于 2577753001471010316917?为什么它不等于 2577753001471010316721 或 257775300147101 之后的任何数字? )))
      • @AndrewKlimov - 您正在准确地查询 2.57775300147101E21;并且没有与该值匹配的行。客户端显示的实际表值四舍五入到它配置的小数点后显示的位数;如果您然后过滤该舍入值,它将找不到任何东西,除非您使用 Bob 显示的范围。问题是显示,而不是数据。 (这类似于人们问为什么在查询显示的值时过滤to_date('15-Apr-21') 上的日期列没有找到任何内容;因为显示截断为当天,隐藏了时间。)
      • @AndrewKlimov 只需打开您的 SQL 客户端设置并找到数字格式设置。
      • 感谢大家的帮助!我发现解决方法只是在 PL/SQL Developer 中应用显示“数字字段 to_char”。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-13
      • 2011-08-24
      • 1970-01-01
      • 1970-01-01
      • 2015-01-20
      • 2011-10-21
      相关资源
      最近更新 更多