Вы бы подумали, что ваш код будет работать. Однако 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;
Похоже у вас есть какие-то не-числовые значения в этом столбце ... – jarlh
Какую версию SQLServer вы используете? – TheGameiswar