【问题标题】:sql for sliding rate card for charges用于收费的滑动费率卡的 sql
【发布时间】:2013-10-31 00:55:03
【问题描述】:

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

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

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;

有关于这个设计的 cmet 吗?有更好的方法吗?

【问题讨论】:

  • 这一切都取决于将对数据库运行的查询。如果您要不断计算成本,那么让它们已经可以使用是有意义的。
  • 您的解决方案应该可以正常工作,但是您需要在每次第一个表更改时重新计算成本,或者如果订单数量的潜在界限增加(这可能不是问题,具体取决于要求您的应用程序)。但是,通过将第一个表加载到应用程序中的数据结构中,并在那里执行必要的计算,可以相对容易和有效地处理这个问题。 SQL 可以做很多事情,但有些任务可以在其他地方更有效地处理。
  • 谢谢大家。费率卡是静态的(大约每年更改一次),所以没有问题。我可以在中间层进行计算,但在数据库中更容易,因为它可以从多个应用程序访问。

标签: sql


【解决方案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
)

【讨论】:

  • 我认为你的方向是正确的,但如果所有行都有value &lt; high(在 where 子句中),那么情况总是会转到 else,对吗?
【解决方案2】:

此查询应该适用于您现有的表结构。它比预先计算的查询要复杂一些,但另一方面,它不使用预先计算的表,当费率发生变化时,它需要为每个使用 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

【讨论】:

    猜你喜欢
    • 2017-11-26
    • 2012-01-13
    • 1970-01-01
    • 2020-11-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-12
    • 2021-05-29
    相关资源
    最近更新 更多