【问题标题】:HSQL filter NaN effectivelyHSQL 有效过滤 NaN
【发布时间】:2012-10-01 10:15:58
【问题描述】:

我有一个由第 3 方代码读取的 HSQL 数据库。此第 3 方代码将某些数值转换为 Double.NaN。我的任务是编写一个 sql 查询,可以将这些数值替换为 null。

在这个项目HSQLDB Statement and Java NaN doubles 我读到 sqrt(-1) 或 0.0/0.0 将被转换为 NaN。但是,对于这个值,相等性测试有点奇怪。考虑这个查询:

select
    casewhen(1=1, 1, 0), -- this one is to make sure that casewhen works as we expect
    casewhen(sqrt(-1)=sqrt(-1), 1, 0), -- this one looks good, we'll see
    casewhen(sqrt(-1)=1, 1, 0) -- this is the odd part, we'll see
from mytable; -- any table with at least 1 row will do

它返回这样的行:

C1 C2 C3
 1  1  1

看起来 sqrt(-1) 等于每个数字。我可以这样调整:

select
    casewhen(1=1, 1, 0),
    casewhen(
        position(
                 '0E0/0E0' in
                 cast(sqrt(-1) to varchar(40))
                ) = 1,
        'NaN', 'Numeric')
 from mytable;

它返回我需要的:

C1  C2
 1 NaN

但我不满意:此解决方案需要从 numeric 转换为 varchar,然后运行 ​​position 函数并检查其返回值以查看它是否会转换为 NaN。您知道在 SQL 级别上更有效的解决方案吗?

【问题讨论】:

    标签: java hsqldb


    【解决方案1】:

    这在 HSQLDB 2.2.9(或更高版本)中可以正常工作。

    第一个 SELECT 语句返回 1,1,0

    试试这个,它只返回具有 NaN 值的行:

    create table t (c varchar(40), d double)
    insert into t values (cast (sqrt(-1) as varchar(40)), sqrt(-1))
    insert into t values (cast (-1 as varchar(40)), -1)
    select * from t where d = sqrt(-1)
    

    旧版本的行为与您的示例类似。

    【讨论】:

    • 是的,遗留代码的诅咒:我们需要修复新版本中修复的问题。谢谢!
    【解决方案2】:

    我找到了一个更快的解决方法:

    select
        casewhen(5 = 5 + 1, 1, 0),
        casewhen(sqrt(-1) = sqrt(-1) , 1, 0)
    from mytable;
    

    将返回如下行:

    C1 C2
     0  1
    

    因此,(x = x + 1) 仅适用于 NaN 值。

    【讨论】:

      猜你喜欢
      • 2022-12-13
      • 2014-07-01
      • 2018-09-02
      • 1970-01-01
      • 2014-09-22
      • 2016-12-24
      • 2017-06-05
      • 2014-05-18
      相关资源
      最近更新 更多