T-SQL中的VLOOKUP样式范围查找

时间:2011-06-09 00:39:08

标签: sql-server tsql sql vlookup

这是一个棘手的问题,我还没有完全理解。我正在使用SQL Server 2008,我有一个稀疏范围表,如下所示:

Range     Profession
-----     ----------
0         Office Worker
23        Construction
54        Medical

然后我有另一个表,其值在这些范围内。我想构建一个连接这两个表的查询,并给我一个小于或等于给定值的Profession值。所以我要说我的另一张桌子是这样的:

Value
29
1
60

然后我想加入我的回归:

Value     Profession
-----     ----------
29        Construction
1         Office Worker
60        Medical

(因为29> 23为施工,但< = 54为医疗)

有没有什么方法可以让SQL以这种方式屈服于我的意愿,而不是实际吹出范围表以包含每一个可能的值?

谢谢。

3 个答案:

答案 0 :(得分:4)

最简单的方法是向稀疏范围表添加另一列。

LowRange       HighRange      Profession
   0              22         Office Worker
  23              53          Construction
  54            999999         Medical

然后使用这样的查询来获取范围(表2是具有29,1,60值的那个):

SELECT Table_2.JoinKey as Value, Table_1.Description as Profession 
  FROM Table_1 INNER JOIN Table_2 
          ON Table_2.JoinKey => Table_1.LowRangeKey 
             AND Table_2.JoinKey <= Table_1.HighRangeKey;

答案 1 :(得分:3)

您可以使用CROSS APPLY:

select v.Value, p.Profession
from tblValues v
cross apply
   (select top(1) pr.Profession
    from tblProfessionRanges pr
    where pr.Range <= v.Value ORDER BY pr.[Range] DESC) p

它应该比使用max更快,并且不需要维持最大范围。

答案 2 :(得分:2)

我想我理解你的问题。我创建了一个名为professions的表,其中包含您的值和一个带有查找值的map_vals表。然后我想出了这个:

select p.range as `range1`, p.profession, v.value from professions p 
inner join map_vals v ON v.value >= p.range
where p.range = 
      (select max(p3.range) from professions p3 where p3.range <= v.value) 
order by v.value

当给出这些值时......

value   
29
0
60
1
23
54

返回

range1  profession  value   
0           Office Worker   0
0           Office Worker   1
23          Construction    23
23          Construction    29
54          Medical         54
54          Medical         60

编辑:

您也可以使用manfred-sorg所示的CROSS APPLY,但需要ORDER BY DESC,否则您将获得以下内容:

select v.Value, p.Profession
from tblValues v
cross apply
   (select top(1) pr.Profession
    from tblProfessionRanges pr
    where pr.Range <= v.Value) p

生成

Value       Profession
----------- --------------------------------------------------
29          Office Worker
1           Office Worker
60          Office Worker

要获得所需的结果,您需要将其更改为:

select v.Value, p.Profession
from tblValues v
cross apply
   (select top(1) pr.Profession
    from tblProfessionRanges pr
    where pr.Range <= v.Value ORDER BY pr.[Range] DESC) p

Value       Profession
----------- --------------------------------------------------
29          Construction
1           Office Worker
60          Medical

但是,此处所需的排序使其效率低于使用MAX