1

首先,让我声明我已经阅读了各种类似的帖子,但无法确定其他发帖者在此错误消息中遇到的问题与我遇到的情况之间的相似之处。也许我没有正确搜索,但这是场景。我正在尝试在表中搜索转换为数值时小于 70 的值。有时该值可以用逗号存储(即 3,080 等),因此我有一个替换语句来删除逗号。下面obsValue查询中的列是varchar(2000),我猜这可能与它有关。我的初始查询有效:

Select name, obsValue
From database.dbo.table
Where name in ('LDL') 
and isnumeric(obsvalue) = 1 
and cast(replace(obsvalue,',','') as decimal(18)) < 70

这会带回预期值,但这不是name我要搜索的唯一值。其他示例包括('LDL(CALC)'). 使用UNION语句将允许我将查询合并在一起,但不幸的是我无法控制应用程序代码,这不是一个选项。我唯一可用的选项是使用IN子句,因此当我搜索各种name值时,最终查询将如下所示:

Select name, obsValue
From database.dbo.table
Where name in ('LDL', 'LDL(CALC)') 
and isnumeric(obsvalue) = 1 
and cast(replace(obsvalue,',','') as decimal(18)) < 70

不幸的是,这样做是我收到错误消息的地方。如果这已经在其他地方得到回答,我深表歉意。请链接,我会在信用到期的地方给予信用。

4

3 回答 3

1

obsvalue 中的值可能对于您的 cast( 作为小数) 函数来说太大了,但无论如何您都不关心,因为它们不符合您的 in() 标准。

尝试在子查询中应用 cast(),将查询限制为实际需要转换的 obsvalues。

此外,由于逗号仅在值大于 999 时才存在,并且您正在测试小于 70 的值,因此不需要替换。事实上,您可以排除任何包含逗号的行,因为您知道它太高了。

于 2012-01-30T16:51:17.573 回答
1

问题是当 IN 子句中有多个项目时,SQL Server 正在以不同的方式优化查询。您可以使用 CASE 语句来防止优化

SELECT name, obsvalue
FROM database.dbo.table 
WHERE (CASE WHEN ( isnumeric(obsvalue) = 1 
             AND name in ('LDL', 'LDL(CALC)')) 
       THEN cast(replace(obsvalue,',','') as decimal(18))
       ELSE null END) < 70
于 2012-01-30T17:45:34.803 回答
1

您可以将 IsNumeric(obsvalue) 替换为 (select obsvalue where isumeric(obsvalue) = 1)。

Select name, obsValue
From database.dbo.table
Where name in ('LDL', 'LDL(CALC)') 
and isnumeric(obsvalue) = 1 
and cast(replace((select obsvalue where isnumeric(obsvalue) = 1),',','') as decimal(18)) < 70
于 2012-01-31T01:25:28.373 回答