我越想到它就越困惑,可能是因为我写了一些复杂的sql已经有一段时间了。
我有一个具有值范围的表。让我们称之为范围:
RANGE
RANGE_ID RANGE_SEQ MIN MAX FACTOR
1 1 0 10 1
1 2 11 100 1.5
1 3 101 2.5
2 1 0 18 1
2 2 19 2
我有一个使用这些范围的表。让我们称之为应用程序
APPLICATION
APP_ID RAW_VALUE RANGE_ID FINAL_VALUE
1 20.0 1 30.0 /*In Range 1, 20 falls between 11 and 100, so 1.5 is applied)*/
2 25.0 2 50.0
3 18.5 2 18.5
我希望得到那些介于范围之间的RAW_VALUES
。因此,对于范围2,我希望那些APP_ID
的{{1}}介于18和19之间。对于范围1,我希望那些RAW_VALUE
之间的APP_ID
10和11以及100和101。
我想知道这是否可以用SQL,以及我可以尝试的一些指示。我不需要sql本身,只是指向该方法的一些指示。
答案 0 :(得分:1)
试试这个让你亲近
select app_id,raw_value,aa.range_id,raw_value * xx.factor as FinaL_Value
from Application_table aa
join range_table xx on (aa.raw_value between xx.min and xx.max)
and (aa.range_id=xx.range_id)
要获得不匹配(即表中不存在的raw_values),请尝试此
select app_id,raw_value,aa.range_id
from Application_table aa
left join range_table xx on (aa.raw_value between xx.min and xx.max)
and (aa.range_id=xx.range_id)
where xx.range_id is null
答案 1 :(得分:1)
create table tq84_range (
range_id number not null,
range_seq number not null,
min_ number not null,
max_ number,
factor number not null,
--
primary key (range_id, range_seq)
);
insert into tq84_range values (1, 1, 0, 10, 1.0);
insert into tq84_range values (1, 2, 10, 100, 1.5);
insert into tq84_range values (1, 3,101,null, 2.5);
insert into tq84_range values (2, 1, 0, 18, 1.0);
insert into tq84_range values (2, 2, 19,null, 2.0);
create table tq84_application (
app_id number not null,
raw_value number not null,
range_id number not null,
primary key (app_id)
);
insert into tq84_application values (1, 20.0, 1);
insert into tq84_application values (2, 25.0, 2);
insert into tq84_application values (3, 18.5, 2);
您想使用left join
。
通过这样的左连接,您可以确保左侧的每个记录
table(在left join
之前出现的表格
select语句文本)将至少返回一次,
即使where条件没有找到记录
在右边的表格中。
如果tq84_range.range is null
,那么您知道加入
条件没有在tq84_range中找到记录,因此,那里
似乎是一个差距。所以你打印Missing:
。
由于tq84_application.max_
可以是null
,因此显示为空
指示无穷大或上限您测试上限
与nvl(tq84_range.max_, tq84_application.raw_value
因此,select语句将变为:
select
case when tq84_range.range_id is null then 'Missing: '
else ' '
end,
tq84_application.raw_value
from
tq84_application left join
tq84_range
on
tq84_application.range_id = tq84_range.range_id
and
tq84_application.raw_value between
tq84_range.min_ and nvl(tq84_range.max_, tq84_application.raw_value);
答案 2 :(得分:0)
根据我的理解,您说您只希望应用程序表中的结果不适合任何范围?例如,这将仅返回app_id = 3的行(我自己的列名称并猜测实际的最小和最大金额):
select *
from APP1 A
where not exists
(select null
from RANGE1 R
where R.RANGE_ID = A.RANGE_ID and A.RAW_VALUE between nvl(R.MINNUM, 0) and nvl(R.MAXNUM, 999999));
但是,当然,它不会返回因子量,因为它不匹配范围表中的任何行,那么为什么上面示例中app_id = 3的结果与factor = 1匹配?如果你的raw_value列是十进制的,那么我希望范围也是十进制的。