You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MyBatis中如何实现行内列全为NULL时total列返回NULL?

问题描述

当前在MyBatis中执行查询后得到如下结果(total列为每行的求和值):

day_1day_2day_3total
[NULL]6[NULL]6
[NULL][NULL][NULL]0

计算total列使用的MyBatis代码如下:

(
  <foreach item="item" collection="dayList" open="" separator=" + " close="">
            COALESCE(day_${item}, 0)
  </foreach>
) AS total

期望的查询结果是:当某行所有列均为[NULL]时,total列返回[NULL],而非0:

day_1day_2day_3total
[NULL]6[NULL]6
[NULL][NULL][NULL][NULL]

尝试过以下代码,但不确定是否可行:

(
      <foreach item="item" collection="dayList" open="" separator=" + " close="">
     <if test="#{'hour_' + item} != null">
        hour_${item}
     </if>
      </foreach>
    ) AS total

需要解决:如何在MyBatis中实现上述需求?

解决方案

方法一:用CASE WHEN判断所有列是否为空

核心逻辑是先判断当前行的所有day_*列是否都为NULL,再决定返回NULL还是求和值:

(
  CASE 
    WHEN <foreach item="item" collection="dayList" open="" separator=" AND " close="">
           day_${item} IS NULL
         </foreach>
    THEN NULL
    ELSE <foreach item="item" collection="dayList" open="" separator=" + " close="">
           COALESCE(day_${item}, 0)
         </foreach>
  END
) AS total

这段代码执行时:

  • 如果所有day_*列都是NULL,total直接返回NULL;
  • 只要有一列非空,就把所有NULL转成0后求和,得到正确的非零结果。

方法二:利用NULLIF简化(适配支持该函数的数据库)

如果你的数据库(如MySQL、PostgreSQL)支持NULLIF函数,可以结合它简化代码:

(
  CASE WHEN <foreach item="item" collection="dayList" open="" separator=" OR " close="">
              day_${item} IS NOT NULL
            </foreach>
       THEN <foreach item="item" collection="dayList" open="" separator=" + " close="">
              COALESCE(day_${item}, 0)
            </foreach>
       ELSE NULL
  END
) AS total

逻辑和方法一一致,只是判断条件换成了“是否存在非空列”,写法更直观。

关于你尝试的代码的问题

你写的<if test="#{'hour_' + item} != null">逻辑不成立:MyBatis的test表达式是在SQL解析阶段执行的,无法直接判断数据库中列的值是否为NULL,所以这段代码不会过滤空列,反而可能因为生成空的求和表达式导致SQL语法错误。

内容的提问来源于stack exchange,提问作者mentha

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 07:15:26