0

我有一张滑动(按比例)价目表,我需要从中向客户收费,我想知道最好的设计。例如,我的价目表是这样的:

(用法是整数而不是浮点数)。

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

因此,例如,如果客户在 0 级使用 15,000 个小部件,他们会被收费:

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

请注意,对于 1-10,000 之间的小部件,客户按 2.00 美元/小部件收费,然后对于 10,001-20,000 之间的小部件按 1.00 美元/小部件收费,依此类推。也就是说,并不是所有小部件都以最便宜的价格收费——“早期”小部件更贵,然后小部件数量越多越便宜。

我正在考虑预先计算费用,这样我就可以在客户和计算的费率之间进行连接。显然,表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;

对此设计有何评论?有什么更好的方法吗?

4

2 回答 2

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
于 2013-10-31T01:26:44.580 回答
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
)
于 2013-10-31T01:07:40.913 回答