我试图在数据库中平均取一列。该列AMOUNT
并存储为NVARCHAR(300),null
。
当我尝试将其转换为数值时,出现以下错误:
消息8114,级别16,状态5,第1
行将数据类型NVARCHAR转换为NUMBER时出错
这就是我现在所拥有的。
SELECT AVG(CAST(Reimbursement AS DECIMAL(18,2)) AS Amount
FROM Database
WHERE ISNUMERIC(Reimbursement) = 1
AND Reimbursement IS NOT NULL
您会认为您的代码可以工作。但是,SQL Server不保证该WHERE
子句在进行转换之前会过滤数据库SELECT
。我认为这是一个错误。在Microsoft看来,这是一项优化功能。
因此,WHERE
不能保证您的工作。即使使用CTE也无法解决问题。
TRY_CONVERT()
SQL Server 2012+中提供了最佳解决方案:
SELECT AVG(TRY_CONVERT(DECIMAL(18,2), Reimbursement)) AS Amount
FROM Database
WHERE ISNUMERIC(Reimbursement) = 1 AND Reimbursement IS NOT NULL;
在早期版本中,您可以使用CASE
。在CASE
不保证条款的顺序排序,那么:
SELECT AVG(CASE WHEN ISNUMERIC(Reimbursement) = 1 AND Reimbursement IS NOT NULL
THEN CONVERT(DECIMAL(18,2), Reimbursement))
END)
FROM Database;
因为AVG()
忽略NULL
值,所以WHERE
没有必要,但是您可以根据需要将其包括在内。
最后,您可以使用计算列来简化代码:
alter database add Reimbursement_Value as
(CASE WHEN ISNUMERIC(Reimbursement) = 1 AND Reimbursement IS NOT NULL
THEN CONVERT(DECIMAL(18,2), Reimbursement))
END);
然后,您可以将代码编写为:
select avg(Reimbursement_Value)
from database
where Reimbursement_Value is not null;
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句