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

使用TIMESTAMPDIFF计算年龄出现NULL值,请求SQL语句排查

问题排查:根据no_id解析出生日期计算年龄时部分age返回NULL

问题场景

根据no_id字段解析出生日期并计算年龄,执行SQL后部分行的age字段返回NULL,而非预期数值。

原SQL语句

select no_id,
    case when substring(no_id,1,2) < Substring(YEAR(NOW()),-2) 
    then Concat('20',substring(no_id,1,2),'-',substring(no_id,3,2),'-', substring(no_id,5,2))
    else
     Concat('19',substring(no_id,1,2),'-',substring(no_id,3,2),'-', substring(no_id,5,2))
    end as dob, TIMESTAMPDIFF(YEAR, no_id, CURDATE()) AS age
from driver_details;

实际表数据

no_idcategory_licensestatus
980401001121D1
970101110101D1

实际执行输出

no_iddobage
9804010011211998-04-0124
9701011101011997-01-01NULL

预期输出

no_iddobage
9804010011211998-04-0124
9701011101011997-01-0125

问题原因

原SQL中TIMESTAMPDIFF(YEAR, no_id, CURDATE())存在核心错误:

  • no_id是12位字符串(如970101110101),MySQL无法将其隐式转换为有效日期格式,导致TIMESTAMPDIFF无法计算,返回NULL。
  • 部分短格式字符串的隐式转换属于侥幸行为,完全不可靠。

修正方案

方案1:用子查询复用已解析的dob

先在子查询中生成标准日期格式的dob,再基于该字段计算年龄:

select no_id, dob, TIMESTAMPDIFF(YEAR, STR_TO_DATE(dob, '%Y-%m-%d'), CURDATE()) AS age
from (
    select no_id,
        case when substring(no_id,1,2) < Substring(YEAR(NOW()),-2) 
            then Concat('20',substring(no_id,1,2),'-',substring(no_id,3,2),'-',substring(no_id,5,2))
            else Concat('19',substring(no_id,1,2),'-',substring(no_id,3,2),'-',substring(no_id,5,2))
        end as dob
    from driver_details
) temp;

方案2:直接在函数内转换日期

将no_id解析为标准日期后传入TIMESTAMPDIFF,避免重复逻辑:

select no_id,
    case when substring(no_id,1,2) < Substring(YEAR(NOW()),-2) 
        then Concat('20',substring(no_id,1,2),'-',substring(no_id,3,2),'-',substring(no_id,5,2))
        else Concat('19',substring(no_id,1,2),'-',substring(no_id,3,2),'-',substring(no_id,5,2))
    end as dob, 
    TIMESTAMPDIFF(YEAR, 
        STR_TO_DATE(
            CONCAT(
                case when substring(no_id,1,2) < Substring(YEAR(NOW()),-2) then '20' else '19' end,
                substring(no_id,1,2),'-',substring(no_id,3,2),'-',substring(no_id,5,2)
            ), 
            '%Y-%m-%d'
        ), 
        CURDATE()
    ) AS age
from driver_details;

验证结果

执行修正后的SQL,两行数据的age字段均能返回预期数值:第二行970101110101对应的age为25。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 00:30:55