2013-10-31 59 views
0

我有一個滑動(按比例)價目表,我需要收取客戶,我想知道最好的設計。例如,我的價目表是這樣的:SQL爲滑動率卡收取費用

(用法是一個整數而不是浮點數)。

Level Usage Rate 
---------------------- 
0  10,000 $2.00 
0  20,000 $1.00 
0  30,000 $0.50 
1  10,000 $4.00 
1  20,000 $2.00 
1  30,000 $1.00 

因此,舉例來說,如果客戶在使用15000只小部件級別0,他們得到充電:

10,000 * 2.00 = $20,000 
5,000 * 1.00 = $ 5,000 
----------------------- 
Total:   $25,000 

注意,客戶得到2.00 $ /插件收取1之間的小部件10,000,然後以1.00美元/小部件的價格在10,001-20,000之間,依此類推。也就是說,他們並不是以所有小部件的最便宜的價格收費 - 「較早」的小部件更昂貴,那麼小部件會以更大的數量更便宜。

我想到預先計算的收費,所以我可以做一個客戶和計算率之間的加入。很明顯,表pre_calc會很大,但磁盤空間很便宜。這比每次計算成本都要快速/簡單。

Table pre_calc 
============== 

Level Usage Cost 
---------------------- 
0   0 $0 
0   1 $2.00 
0   2 $4.00 
... etc 
1   0 $0 
1   1 $4.00 
1   2 $8.00 
... etc 

讓我做

SELECT c.name, p.cost 
FROM customers as c 
INNER JOIN pre_calc as p 
ON c.level = p.level AND c.usage = p.usage; 

這種設計有何評論?任何更好的方法來做到這一點?

+0

這一切都取決於將針對數據庫運行的查詢。如果您不斷計算成本,那麼讓他們已經在那裏使用是有意義的。 –

+0

您的解決方案應該可以正常工作,但每當第一個表更改時,或者訂單數量的潛在範圍增加(這可能不是問題,取決於您的應用程序的要求),您都需要重新計算成本。但是,通過將第一個表加載到應用程序中的數據結構中並在那裏執行必要的計算,可以相對簡單高效地處理此問題。 SQL可以做很多事情,但是其他任務可以更有效地處理一些任務。 –

+0

謝謝你們。價目表是靜態的(每年更換一次),所以沒有問題。我可以在中間層執行calc,但在db中執行會更容易,因爲它將從多個應用程序訪問。 –

回答

1

這樣的事情呢?

level low  high  price 

0  0  10000  20000 
0  10000 20000  10000 
0  20000 30000  5000 

然後SQL:

select sum(p) from (
    select case 
    when $value$ > high 
     then price 
     else ($value$ - low)/(high - low) * price 
    end as p 
    from ... 
    where $value$ < high 
) 
+0

我認爲你是在正確的方向,但如果所有的行都有''value acfrancis

+0

iluxa - 謝謝,我會給它一個。 –

1

此查詢應該與您現有的表結構。這比預先計算的查詢複雜一點,但另一方面,它不使用預先計算的表,當費率變化時,需要爲每個用法的int值更新。我的猜測是,這裏的表現會比預先計算的更糟糕,但是隻有在測試的時候你纔會知道。

SELECT c.name, 
    -- The usage rates less than or equal to the customer's usage 
    (SELECT SUM(r.Rate * r.Usage) 
    FROM Rates r 
    WHERE r.Level = c.Level and r.Usage <= c.Usage) + 
    -- The rate from the usage rate immediately above the customer's level 
    -- using the usage top limit from the rate immediately less or equal to the customer's usage 
    (SELECT TOP 1 r2.Rate * (c.Usage - (SELECT TOP 1 r3.Usage FROM Rates r3 
             WHERE r3.Level = c.Level and r3.Usage <= c.Usage 
             ORDER BY Usage DESC)) 
    FROM Rates r2 
    WHERE r2.Level = c.Level and r2.Usage > c.Usage 
    ORDER BY Usage ASC) as cost 
FROM customers as c 
+0

不錯,謝謝,我會玩! –