跳到主要内容

try_divide:安全除法

速查结论

try_divide(dividend, divisor) 是 Spark SQL 中用于**防止"除以0报错"**的函数。它始终执行浮点除法,当 divisor 为 0 时优雅地返回 NULL 而不是中断任务。区别于普通 / 除法(除零会报错),try_divide 是安全版本。

语法

try_divide(dividend, divisor)

参数说明

参数说明
dividend被除数,必须是数值类型或 interval 类型
divisor除数,必须是数值类型

返回值:dividend / divisor 的浮点结果。divisor 为 0 时返回 NULL。

Since: 3.2.0

示例

基础除法

-- 整数除法,返回浮点结果
SELECT try_divide(3, 2);
-- 结果: 1.5

-- LONG 类型除法
SELECT try_divide(2L, 2L);
-- 结果: 1.0

除零安全处理

-- 除零不报错,返回 NULL
SELECT try_divide(1, 0);
-- 结果: NULL

-- 普通 / 除零会报错
SELECT 1 / 0;
-- 报错: division by zero

Interval 类型除法

-- interval 除以数值
SELECT try_divide(interval 2 month, 2);
-- 结果: 0-1 (1 month)

-- interval 除零也安全返回 NULL
SELECT try_divide(interval 2 month, 0);
-- 结果: NULL

try_divide vs / vs div 对比

运算除零行为结果类型适用场景
try_divide(a, b)返回 NULL始终浮点数据不规整、除数可能为 0
a / b报错取决于操作数类型数据规整、除数确保非 0
a DIV b报错整数整数除法取商
-- try_divide: 除零安全,返回 NULL
SELECT try_divide(10, 0);
-- 结果: NULL

-- /: 除零报错
SELECT 10 / 0;
-- 报错: / by zero

-- DIV: 整数除法
SELECT 10 DIV 3;
-- 结果: 3

选型建议

  • 数据可能含 0 除数(如用户输入、日志数据):用 try_divide
  • 数据规整、除数确保非 0:用 /,性能更好
  • 整数取商:用 DIV

常见报错与避坑指南

try_divide 始终返回浮点

即使两个操作数都是整数,结果也是浮点数。这在需要整数结果的场景下可能产生意外。

-- try_divide 返回浮点,即使两个整数相除
SELECT try_divide(10, 4);
-- 结果: 2.5(不是 2)

-- 如需整数结果,用 CAST 转换
SELECT CAST(try_divide(10, 4) AS INT);
-- 结果: 2

divisor 类型必须是数值

divisor 必须是数值类型,不能是 interval 或其他类型。

-- 错误写法:divisor 不能是 interval
SELECT try_divide(10, interval 2 month);
-- AnalysisException: cannot resolve ...

-- 正确写法:divisor 必须是数值类型
SELECT try_divide(10, 2);
-- 结果: 5.0

NULL 值传播

任一参数为 NULL 时,结果也为 NULL。

-- dividend 为 NULL
SELECT try_divide(NULL, 2);
-- 结果: NULL

-- divisor 为 NULL
SELECT try_divide(10, NULL);
-- 结果: NULL

-- 与 coalesce 配合设置默认值
SELECT coalesce(try_divide(amount, total), 0) AS ratio
FROM sales;
📱关注公众号

「数据仓库技术」文章同步更新,不错过每一篇干货

微信公众号二维码
💬加群交流

备注「数据仓库技术」加入社群,每日一道大厂SQL真题

交流微信二维码

你可能还想看