PAYATHON 2026

Apache IoTDB 如何按顺序返回首个非 NULL 且大于 0 的值?

数据阿明

结论

可以用 CASE WHEN 按 real_temp、backup_temp、default_temp 的顺序判断,返回第一个大于 0 的值。如果想保留 COALESCE,可以先用 CASE 将不符合条件的值转换为 NULL。

COALESCE 只跳过 NULL,不会跳过 0 或负数,因此原查询返回 -5.0、-10.0 符合它的定义。IoTDB 表模型文档列出了 CASE 和 COALESCE 的条件表达式语法,详见官方基础函数文档。

直接使用 CASE

SELECT
    CASE
        WHEN real_temp > 0 THEN real_temp
        WHEN backup_temp > 0 THEN backup_temp
        WHEN default_temp > 0 THEN default_temp
    END AS final_temp
FROM sensor_data
ORDER BY time;

CASE 按条件出现的顺序选择第一个为 TRUE 的分支。省略 ELSE 时,如果没有条件为 TRUE,结果就是 NULL。

不必额外写 IS NOT NULL。字段为 NULL 时,字段 > 0 的结果是未知值,不会匹配 WHEN 分支;字段为 0 或负数时,该条件也不会匹配。

根据题目中的三行数据,按时间排序后的预期结果为:

+----------+
|final_temp|
+----------+
|      25.0|
|      NULL|
|      30.0|
+----------+

第 1 行匹配 default_temp,第 2 行没有匹配的分支,第 3 行首先匹配 real_temp。

保留 COALESCE 的写法

也可以对每个候选字段使用 CASE,只保留大于 0 的值:

SELECT
    COALESCE(
        CASE WHEN real_temp > 0 THEN real_temp END,
        CASE WHEN backup_temp > 0 THEN backup_temp END,
        CASE WHEN default_temp > 0 THEN default_temp END
    ) AS final_temp
FROM sensor_data
ORDER BY time;

每个 CASE 在条件不成立时返回 NULL,COALESCE 随后按参数顺序返回第一个非 NULL 的结果。如果三个结果都是 NULL,最终结果也是 NULL。

注意事项

  • 字段顺序决定优先级。这两种写法都不会比较三个字段并选取最大值。
  • 不要用 WHERE 过滤掉不满足条件的整行,否则全部无效的那一行会被删除,无法保留其 final_temp = NULL 的结果。
  • NULLIF(real_temp, 0) 只能将等于 0 的值变成 NULL,不能排除负数。
  • 原始示例中用反引号包裹 NULL 的写法需要修正。SQL 空值应写成不带引号或反引号的 NULL。
  • 上述结果是根据示例数据推导的预期结果,未在 Apache IoTDB 2.0.6 实例上实际执行验证。

备注:内容仅供参考。