2011-12-19 84 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);