第一步,先建立一张表,我们先忽略一些其他的问题,比如建立索引等等,只关注具体的问题。
create table p_rate ( div number(2) not null, rate number(10,2) not null, PRIMARY KEY (div) )
假设在表中已经存在了下面这样的数据:
+-------div------rate-------+
|---------0----------1.00-------+
|---------30---------1.10-------+
|---------50---------1.20-------+
|---------90---------1.30-------+
从表中可以看出当p落在不同的区间是的取值:
当0<=p<30时,应该取0对应的比率;
当30<=p<50时,应该取30对应的比率;
当50<=p<90时,应该取50对应的比率;
当90<=p时,应该取90对应的比率。
我是这样分析的:先用录入的值p减去每一个divisor,并作为一个新的列,即使用下面的查询语句:
select div,p-div from p_rate
注:这里的p会从其他地方取得,在执行sql的时候就是具体的值了。
这样的话,就能求出来p和div的差了,就在这个差上做文章(这个文章不出轨 )!
针对一些特殊的录入值p,列举一些值的话,就会出现下面的这种情况
序号 | div | p=0 | p=10 | p=30 | p=40 | p=60 | p=90 | p=100 |
1 | 0 | 0 | 10 | 30 | 40 | 60 | 90 | 100 |
2 | 30 | -30 | -20 | 0 | 10 | 30 | 60 | 70 |
3 | 50 | -50 | -40 | -20 | -10 | 10 | 40 | 50 |
4 | 90 | -90 | -80 | -60 | -50 | -30 | 0 | 10 |
可以从这些数据中看到所取到的每个div,对应的p-div,都是取的差是最小的非负数,这就是突破点了。
再把这个问题分解一下,就是变成了取一个表的最小的非负数了。
可以用下面的SQL:
select min(div) from (select div,p-div as pd from p_rate) where pd>=0
经过上面一步,已经知道小于或等于录入值p的最大的div,剩下的就是从p_rate 表中取该div对应的rate了。把SQL写出来就是这样的:
select rate from p_rate where div = (select min(div) from (select div,p-div as pd from p_rate) where pd>=0)
再提供一个写法,和上面的逻辑一模一样,只是换了一个写法,这种做法可能更多的用在一些字段比较多的报表的SQL中,在这儿体现不出它的优势
with tmp as (select div,p-div as pd from p_rate) select rate from p_rate where div = (select min(div) from tmp where pd>=0)
再次的,无比热切的欢迎更好的思路和方法 ,最好是一个自带的function就能解决问题