[Oracle]求不大于录入值的最大值

今天因为业务需要,要从一个表中取不大于录入值的最大值,即有一张表,里面有一个因子,是一些等级,针对每个等级,都有一个比率,本来录入的值一定是和等级相等的,现在用户提出,要支持录入一些不是标准的等级的值,可以按照一定的规则,取小于或等于录入的等级的最大等级的比率。这个是简化了的业务逻辑,为了说明这个问题,把这个问题尽量简化了说,提供一个思路,供大家讨论,欢迎大拿帮忙提供更好的方法
第一步,先建立一张表,我们先忽略一些其他的问题,比如建立索引等等,只关注具体的问题。
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就能解决问题

猜你喜欢

转载自jiiming.iteye.com/blog/2040213