我有一个CTE查询,它将varchar字段转换为小数。
但是,在CTE之后的SELECT
我想限制返回的值。
这是我得到
关节炎溢出错误
这是查询:
;WITH CTE
AS
(
SELECT PP.PatientProfileID,
ROUND(CAST( CASE WHEN ISNUMERIC(O.Value) = 1 THEN O.Value END AS DECIMAL(4, 1)), 1) AS BmiValue
FROM PatientProfile PP RIGHT OUTER JOIN Encounter E1 ON PP.PatientProfileID = E1.PatientProfileID
JOIN Procedures P on E1.PatientEncounterID = P.PatientEncounterID
JOIN Observation O ON O.PatientProfileID = E1.PatientProfileID
WHERE P.CPTCode = '3008F' AND
O.Term = 'BMI' AND O.Value IS NOT NULL
)
SELECT *
FROM CTE
WHERE BmiValue >= 18.5 AND BmiValue < 25.0
当我将where子句限制为:WHERE BmiValue >= 18.5
时,没有错误。
当我只使用WHERE BmiValue < 25.0
时,没有错误。
只有当我使用两个表达式时才会出现算术溢出错误。
查询有什么问题?
更新
正如我在评论中所说,我使用的是SQL SERVER 2008 R2。
我在CTE中消除了十进制值的空值。当我删除WHERE
子句时,BmiValue
的所有值都显示为十进制值。
如果我将BmiValues
的选择范围缩小到此WHERE
条款:
WHERE (BmiValue >= 18.5) AND (BmiValue < 30.0)
没有算术溢出错误。
当我将最大值更改为:
WHERE (BmiValue >= 18.5) AND (BmiValue < 29.0)
我得到算术溢出错误......很奇怪。
答案 0 :(得分:4)
由于这是一个溢出错误,您可以尝试增加GetCallerIdentity
的大小。不能保证decimal()
没有其他问题。
cast()
在Sql Server 2012及更高版本中:当转换失败而不是错误时,每个都会返回;with CTE as (
select PP.PatientProfileID
, ROUND(CAST(case when ISNUMERIC(O.Value) = 1 then O.Value end as decimal(19, 6)), 1) as BmiValue
from PatientProfile PP
right join Encounter E1 on PP.PatientProfileID = E1.PatientProfileID
inner join Procedures p on E1.PatientEncounterID = p.PatientEncounterID
inner join Observation O on O.PatientProfileID = E1.PatientProfileID
where p.CPTCode = '3008F' and O.Term = 'BMI' and O.Value is not null
)
select *
from CTE
where BmiValue >= 18.5 and BmiValue < 25.0
。
答案 1 :(得分:2)
你可能试图在空值上运行数学。
1)ISNUMERIC()
不仅仅是数字(包括' - ','+','$'等)返回true。请转而使用TRY_CAST()
。
2)您的CASE语句需要ELSE子句。否则,您尝试CAST
任意ISNUMERIC() = false
(即空值)到DECIMAL
。
除此之外,在where子句中使用BETWEEN
- 只是更清洁。