2011-12-19 89 views
3

我越想越多,我感到困惑,可能是因为我写了一些复杂的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 S作和19类似地,对于范围1 RAW_VALUE 18之间,我想那些APP_ID s表示具有RAW_VALUE 10和11和100和101之间

我想知道这是否可能与SQL,以及一些我可以尝试的指针。我不需要sql本身,只是一些指向方法的指针。

回答

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 
+0

'我不需要sql本身,只是一些指向这个方法的指针。' – 2011-12-19 22:27:27

+2

有些事情更容易用SQL来说明然后用英文拼写出来。 – Sparky 2011-12-19 22:29:49

+0

这也包括范围内的值。对于范围“1 - 10”和“11 - 20”,我只需要那些介于10和11之间的值。所以我想'10.5'但不是'5'。 – Nivas 2011-12-19 22:35:35

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列将是十进制的,那么我认为范围也是十进制的。

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

有了这样一个左连接,可以确保左 表的每个记录(在 select语句文本之前left join出现的表),将至少有一次回来, 即使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);