SQL使用行值范围选择记录

时间:2015-02-08 09:26:17

标签: sql sql-server

我有以下数据库记录

ID    Weight    Cost
1     3         1.00
2     10        2.00
3     14        3.00

我想要的是获取给定重量的成本。因此,如果我的体重是5,那么费用将是2.00。

澄清,范围将是:

Cost 1.00, weight 0-3
Cost 2.00, weight 4-10
Cost 3.00, weight 11-14

我不确定应该使用什么SQL来获取行范围,但是使用列,我可以使用SELECT Cost FROM table1 WHERE column1 BETWEEN x AND y

欢迎任何建议/意见。

2 个答案:

答案 0 :(得分:0)

这就是你要追求的吗?

http://sqlfiddle.com/#!6/b5307/20

declare @Weight int = 5

select top 1 cost
from weightings
where weight >= @Weight
order by weight 

答案 1 :(得分:0)

有几种方法可以做到这一点,也许最简单的方法是根据表格中的间隔生成一系列权重/成本。为此,我们可以使用数字/计数表(在这种情况下,我使用具有合适数字范围的master..spt_values表)。

所以给出了一个像这样的表:

declare @t table (ID int, Weight int, Cost decimal(10,2))
insert @t values (1, 3, 1.00),(2, 10, 2.00),(3, 14, 3.00)

我们可以定义查询的两个版本(为方便起见,包含在公共表表达式中)。第一个版本使用lag()窗口函数,并且需要比2012年更新的SQL Server版本:

;with costs1 (weight, cost) as (
    select number, cost 
    from master..spt_values 
    inner join (
       select isnull(LAG(weight) over (order by id)+1,0) low, weight high, cost from @t 
    ) t on number <= t.high and number >= t.low
    where type= 'P'
)

select cost from costs1 where weight = 5;

第二个版本不依赖于lag(),而是使用自联接:

;with costs2 (weight, cost) as (
    select number, cost
    from master..spt_values 
    inner join (
       select 
       isnull(t2.weight + 1,0) as low, 
       t1.Weight as high, 
       t1.Cost 
    from @t t1 
    left join @t t2 on t1.ID - 1 = t2.ID 
    ) t on number <= t.high and number >= t.low
    where type= 'P'
    )

select cost from costs2 where weight = 5

另一种选择是计算每个范围的低点/高点并进行如下查询:

select cost from (
    select isnull(LAG(weight) over (order by id)+1,0) low, weight high, cost from @t
    ) t 
where 5 between low and high

Sample SQL Fiddle以及上述查询。