获取范围之间的值

时间:2011-12-19 22:23:46

标签: sql oracle

我越想到它就越困惑,可能是因为我写了一些复杂的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本身,只是指向该方法的一些指示。

3 个答案:

答案 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列是十进制的,那么我希望范围也是十进制的。