4

我有一张带有字母数字代码的表格。在这个特定的例子中,我不关心本质上是字母数字的代码,只关心那些包含整数的代码。我写了一个小查询来查找我需要的代码子集:

 select CAST(icd as float) as icd

from
(
select i.icd
    from icd as i
    where icd like '952%' or icd like '806%' or icd like '3440%' or icd like '3441'
)t

这将返回我需要的代码列表。但是,当我尝试使用 where 子句时:

where icd between 80600 and 80610查询失败,告诉我它无法将 varchar 数据类型转换为 int。但是,如果我做类似的事情

select CAST(icd as float) as icd,icd+10

from
(
select i.icd
    from icd as i
    where icd like '952%' or icd like '806%' or icd like '3440%' or icd like '3441'
)t

我可以在每个代码中添加 10 并且它运行,这意味着它们实际上是整数。我想使用这样的where子句,因为代码 80600-80610 应该标记为 X,而 80611-80620 它们应该标记为 Y。我可以为每个代码手动执行此操作,但我希望比这更可扩展。

如何确保 SQL Server 在使用此 where 子句时只查看派生表,而不是失败?

4

3 回答 3

3

您的内部查询可能返回 varchar 字段。你能跑吗

select i.icd
from icd as i
where icd like '952%' or icd like '806%' or icd like '3440%' or icd like '3441'

并确保没有返回字符串数据?

仅供参考,由于您使用的是内部查询,您可以添加

WHERE IsNumeric(t.icd ) = 1 

确保只返回整数

于 2012-10-23T13:54:13.357 回答
1

在转换结果之前运行过滤器

您正在做的是在查询运行时转换结果而不是列值(并进行所有过滤)。where在转换结果值之前评估过滤器(子句)。

为了仍然使用您在示例中显示的相同结果集,最简单的方法是使用 CTE 而不是子查询,然后对其进行额外的过滤:

with codes as (
    select cast(icd as int) as icd
    from icd
    where icd like '952%' or
          icd like '806%' or
          icd like '3440%' or
          icd like '3441'
)
select icd, 'X' as label
from codes
where icd between 80600 and 80610
union all
select icd, 'Y'
from codes
where icd between 80611 and 80620

CTE 是否比子查询更具可读性是一个无休止的讨论/争论的问题。但是在这种情况下,我们重用相同的表表达式来获得XY标记的结果,与对子查询执行相同操作时所需的代码相比,它使用的代码更少。在这种情况下,它的可读性要高得多。

要转换的数据当然必须是数字

当您转换数据时,您必须确保它实际上可以转换为结果类型。如果您的值是064 V这显然不是一个数字,因此不能转换。致电isnumeric可以在这里提供帮助:

with codes as (
    select cast(icd as int) as icd
    from icd
    where isnumeric(icd) = 1 and
          (
              icd like '952%' or
              icd like '806%' or
              icd like '3440%' or
              icd like '3441'
          )
)
select icd, 'X' as label
from codes
where icd between 80600 and 80610
union all
select icd, 'Y'
from codes
where icd between 80611 and 80620
于 2012-10-23T13:53:25.063 回答
1

您需要确保您的 where 过滤器将 ICD 视为字符串(确实如此),然后仅过滤那些可转换为数字的 ICD。

特别要注意的是,字符串比较需要注意数字的“长度”(例如,“8061”位于“80600”和“80610”之间),但幸运的是,您的过滤器似乎位于长度是恒定的。

例如

where icd between '80600' and '80610' -- i.e. exclude '12345' and 'Apple'
      and length(icd) = 5             -- i.e. exclude '8061' and '806000001'
      and isnumeric(icd) = 1          -- i.e. exclude '8060A' 
于 2012-10-23T13:54:24.987 回答