为何SQL Server中使用AVG()仍需类型转换才能获取浮点值?
关于SQL Server中AVG函数返回整数结果的疑问解答
问题背景
在解决LeetCode「确认率」问题时,编写了以下SQL Server语句:
select s.user_id,round(avg(cast(case when c.action='confirmed' then 1 else 0 end as float) ),2) as confirmation_rate from Signups s left join Confirmations c on s.user_id=c.user_id group by s.user_id
该语句能得到正确的小数结果,但如果移除CAST(... as float)转换,AVG()返回的是取整后的整数,导致结果错误。原本以为AVG()会直接返回浮点值,对此存在困惑。
原因解析
SQL Server的AVG()函数返回值的类型由输入参数的数据类型决定,并非默认返回浮点型:
- 当CASE表达式返回
1或0时,这两个值属于int(整数)类型,因此AVG()会基于整数类型执行计算,最终返回int类型结果——整数除法会直接舍弃小数部分,只保留整数位,自然得不到正确的小数确认率。 - 当通过
CAST(... as float)将CASE的结果转换为浮点型后,AVG()的输入变为浮点类型,计算时会保留小数部分,最终返回浮点型结果,此时ROUND()就能正确处理得到两位小数的结果。
另外可以简化写法:直接用1.0和0.0代替1和0,让CASE表达式直接返回浮点型,无需额外的CAST转换,示例如下:
select s.user_id,round(avg(case when c.action='confirmed' then 1.0 else 0.0 end),2) as confirmation_rate from Signups s left join Confirmations c on s.user_id=c.user_id group by s.user_id
内容的提问来源于stack exchange,提问作者Ashok Kumar Singh
相关产品推荐
相关产品推荐

