【问题标题】:How do I filter out NaN FLOAT values in Teradata SQL?如何在 Teradata SQL 中过滤掉 NaN FLOAT 值?
【发布时间】:2012-11-09 03:17:08
【问题描述】:

使用 Teradata 数据库,可以通过 Java 将 NaN、-Inf 和 +Inf 的值加载到 FLOAT 列中。不幸的是,一旦这些值进入表中,在编写需要过滤掉它们的 SQL 时就会变得很困难。没有 IsNaN() 函数,您也不能“CAST ('NaN' as FLOAT)”并使用相等比较。

我想做的是,

SELECT
  SUM(VAL**2)
FROM
  DTM
WHERE
  NOT ABS(VAL) > 1e+21 AND
  NOT VAL = CAST ('NaN' AS FLOAT)

但失败并出现错误 2620,“格式或数据包含错误字符。”,特别是在 CAST 上。我尝试了简单的“... AND NOT VAL = 'NaN'”,它也因类似原因而失败(3535,“字符串转换为数值失败。”)。我似乎无法弄清楚如何在 SQL 语句中表示 NaN。即使我可以在 SQL 语句中成功表示 NaN,我也会担心比较会失败。根据 IEEE 754 规范,NaN = NaN 应该评估为假。我真正需要的是一个 IsNaN() 函数。然而这个功能似乎并不存在。

【问题讨论】:

    标签: sql teradata


    【解决方案1】:

    我想出了一个变通办法,我将与那些正在寻找解决方案的人分享。但首先,对我来说很明显,Teradata 对 NaN 浮点值的处理是不完整的,我偶然发现的任何行为都可能是无意的,并且在不同版本之间不一致。因此,我提供以下免费建议,不提供任何形式的保证、承诺或责任。警告购买者。

    深入研究数据后,我发现如果我将 FLOAT 值转换为 VARCHAR(50),则 NaN 值会以 22 个星号 (**********************) 的字符串形式出现。我可以改为转换为 VARCHAR(1),NaN 以单个星号 (*) 的形式出现。这种比较还不错。

    SELECT
      SUM(VAL**2)
    FROM
      DTM
    WHERE
      NOT CAST (VAL AS VARCHAR(1)) = '*' AND
      ABS(VAL) < 1.0e+21
    

    我会注意两点。

    首先,我最初对我的 Teradata 版本的“NOT ABS(VAL) > 1.0e+21”的愿望似乎在幕后转换为“ABS(VAL) ”到“= 1.0e+21”工作正常(但看起来很难看)。使用“ABS(VAL)

    其次,虽然我无法始终如一地重现它,但在我的历史中有一些例子,其中“ABS(VAL)

    【讨论】:

      猜你喜欢
      • 2018-09-02
      • 1970-01-01
      • 2017-09-17
      • 2022-09-22
      • 1970-01-01
      • 2011-04-03
      • 2021-02-12
      • 1970-01-01
      • 2021-09-30
      相关资源
      最近更新 更多