`
jiiming
  • 浏览: 7227 次
  • 性别: Icon_minigender_1
社区版块
存档分类
最新评论

[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,列举一些值的话,就会出现下面的这种情况
序号divp=0p=10p=30p=40p=60p=90p=100
1001030406090100
230-30-20010306070
350-50-40-20-10104050
490-90-80-60-50-30010


可以从这些数据中看到所取到的每个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就能解决问题
0
0
分享到:
评论

相关推荐

    Oracle SQL高级编程(资深Oracle专家力作,OakTable团队推荐)--随书源代码

    8.6.1 例子:使用First_value来计算最大值 206 8.6.2 例子:使用Last_value来计算最小值 207 8.7 其他分析函数 207 8.7.1 Nth_value(11gR2) 207 8.7.2 Rank 209 8.7.3 Dense_rank 210 8.7.4 Row_number 211 ...

    C#程序开发范例宝典(第2版).part13

    实例195 获取显示设备的最大、最小及当前刷新率 281 实例196 隐藏控制面板中的声音设备 281 实例197 获取显示设备的当前显示模式 282 实例198 获取声音设备的名称及PNPDeviceID 283 实例199 语音计算器 284 5.5...

    C#程序开发范例宝典(第2版).part08

    实例195 获取显示设备的最大、最小及当前刷新率 281 实例196 隐藏控制面板中的声音设备 281 实例197 获取显示设备的当前显示模式 282 实例198 获取声音设备的名称及PNPDeviceID 283 实例199 语音计算器 284 5.5...

    C#程序开发范例宝典(第2版).part02

    实例195 获取显示设备的最大、最小及当前刷新率 281 实例196 隐藏控制面板中的声音设备 281 实例197 获取显示设备的当前显示模式 282 实例198 获取声音设备的名称及PNPDeviceID 283 实例199 语音计算器 284 5.5...

    C#程序开发范例宝典(第2版).part12

    实例195 获取显示设备的最大、最小及当前刷新率 281 实例196 隐藏控制面板中的声音设备 281 实例197 获取显示设备的当前显示模式 282 实例198 获取声音设备的名称及PNPDeviceID 283 实例199 语音计算器 284 5.5...

    Java开发实战1200例(第1卷).(清华出版.李钟尉.陈丹丹).part3

    实例188 泛型化接口与最大值 239 实例189 使用通配符增强泛型 240 实例190 泛型化的折半查找法 241 第9章 编程常用类 343 9.1 Calendar类的使用 244 实例191 简单的数字时钟 244 实例192 简单的电子时钟 245 实例193...

    vc++ 开发实例源码包

    代码里用了备份dll的方法,因此在自定义的函数中可以直接调用在内存中备份的dll代码,而不需要再把函数头部改来改去。 IOCP反弹远控客户端模型,外加上线服务端,全部代码注释! 如题。这个是IOCP远程控制软件的...

    vc++ 应用源码包_1

    知道的人不多,但提起国内的暴风影音,我想知道的人就多了,其实暴风影音就是Media Player Classic,暴风影音只是同我一样从Gabest官方下载到了Media Player Classic的源码,不同的是,暴风影音将Media Player Classic改成...

    vc++ 应用源码包_2

    知道的人不多,但提起国内的暴风影音,我想知道的人就多了,其实暴风影音就是Media Player Classic,暴风影音只是同我一样从Gabest官方下载到了Media Player Classic的源码,不同的是,暴风影音将Media Player Classic改成...

Global site tag (gtag.js) - Google Analytics