2015-02-08 26 views
-2

我有以下的數據庫記錄SQL選擇記錄使用行的範圍值

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

歡迎任何建議/意見。

+0

我沒有得到邏輯。你能解釋一下嗎? – 2015-02-08 09:35:02

+0

我不清楚。擴大測試數據... – 2015-02-08 09:35:50

+1

你的意思是12應該返回2.00?在這種情況下,請選擇top 1 ...,其中weight 2015-02-08 09:37:10

回答

0

這是你在追求什麼?

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

declare @Weight int = 5 

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

對於5 OP想要1.00,你的查詢返回2.00 – 2015-02-08 09:55:40

+0

@GiorgiNakeuri所以他這樣做。在那種情況下,我不明白他試圖實施的邏輯。 :) – FJT 2015-02-08 10:13:53

+0

啊,OP現在改變了它。 5返回2。 – FJT 2015-02-09 09:51:40

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()窗口功能,需要一個版本的SQL Server 2012更新比:

;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與QUER以上。