2016-08-03 17 views
0

我有一個要求根據產品數量獲得批准限額。 例如 - 如果產品數量小於10000,則獲得相應的批准人。基於產品的有條件批准水平

  • 如果產品數量超過10000,小於50000時,則獲得低於10000極限

  • 相應的審批人和人如果產品數量爲50000,減少超過10萬時,則得到相應的批准人及以下50000極限

  • 所有人如果產品數量超過10萬且小於大於500000,然後獲得相應的審批人,100000以下限制

  • 所有人

是否有可能在不對產品數量和審批限制進行硬編碼的情況下實現此目標,這意味着它應該是動態的,因爲表格中的值會發生變化。

+0

我不確定這是否仍然清楚;你可以添加你期望看到的結果,以及迄今爲止嘗試過的結果嗎?(也不知道爲什麼你在'pos_t'中有重複/非規範化的數據,但希望這只是一個演示) –

+0

您的案例表達式與50000中的任何內容都不匹配,我想這是一個錯誤;你只需要在每個分支中進行檢查?但是,它應該與上級2,3和4匹配;你爲什麼期望它匹配1和2? –

回答

1

至於我可以告訴你只需要加入你的表togather:

select pos_t.* 
from prod_t 
join pos_t on pos_t.username = prod_t.username 
and pos_t.approval_limit <= prod_t.product_amt 
where prod_t.prod_id = 'BC45' 
and prod_t.product_amt = 50000; 

USERNAME    NAME   POSITION  SUPERIOR_POSITION_LEVEL_ID SUPERIOR_POSITION_NAME SUPERIOR_NAME SUPERIOR_USERNAME SUPERIOR_P APPROVAL_LIMIT 
-------------------- --------------- --------------- -------------------------- ------------------------- --------------- ----------------- ---------- -------------- 
C1256    James   Fin. Analyst        1 Sen.Analyst    Ford   12735     782   10000 
C1256    James   Fin. Analyst        2 Manager     Smith   329822     6218   50000 

隨着12000 product_amt它只返回高級職位1 ;對於120000它返回1,2和3;爲500000它返回1,2,3和4.這似乎是你正在描述和期望。

如果你只有prod_id那麼你可以得到所有值的水平,在這種情況下,你需要一個distinct

select distinct pos_t.* 
from prod_t 
join pos_t on pos_t.username = prod_t.username 
and pos_t.approval_limit <= prod_t.product_amt 
where prod_t.prod_id = 'BC45'; 

USERNAME    NAME   POSITION  SUPERIOR_POSITION_LEVEL_ID SUPERIOR_POSITION_NAME SUPERIOR_NAME SUPERIOR_USERNAME SUPERIOR_P APPROVAL_LIMIT 
-------------------- --------------- --------------- -------------------------- ------------------------- --------------- ----------------- ---------- -------------- 
C1256    James   Fin. Analyst        1 Sen.Analyst    Ford   12735     782   10000 
C1256    James   Fin. Analyst        4 Chief Executive   Scott   13457     2987   500000 
C1256    James   Fin. Analyst        2 Manager     Smith   329822     6218   50000 
C1256    James   Fin. Analyst        3 General Manager Finance Jack   23512     727   100000 

或者找到該prod_id最高product_amt和限制的是,這將得到同樣的答案,但效率會更高,例如喜歡的東西:

select pos_t.* 
from (
    select max(username) keep (dense_rank last order by product_amt) as username, 
    max(product_amt) as product_amt 
    from prod_t 
    where prod_id = 'BC45' 
) prod_t 
join pos_t on pos_t.username = prod_t.username 
and pos_t.approval_limit <= prod_t.product_amt; 

USERNAME    NAME   POSITION  SUPERIOR_POSITION_LEVEL_ID SUPERIOR_POSITION_NAME SUPERIOR_NAME SUPERIOR_USERNAME SUPERIOR_P APPROVAL_LIMIT 
-------------------- --------------- --------------- -------------------------- ------------------------- --------------- ----------------- ---------- -------------- 
C1256    James   Fin. Analyst        1 Sen.Analyst    Ford   12735     782   10000 
C1256    James   Fin. Analyst        2 Manager     Smith   329822     6218   50000 
C1256    James   Fin. Analyst        3 General Manager Finance Jack   23512     727   100000 
C1256    James   Fin. Analyst        4 Chief Executive   Scott   13457     2987   500000 

或者,如果你想爲每個product_amt匹配數據的同時,你可以省略distinct,並且包括金額,以便知道它與哪個匹配:

select prod_t.product_amt, pos_t.* 
from prod_t 
join pos_t on pos_t.username = prod_t.username 
and pos_t.approval_limit <= prod_t.product_amt 
where prod_t.prod_id = 'BC45'; 

PRODUCT_AMT USERNAME    NAME   POSITION  SUPERIOR_POSITION_LEVEL_ID SUPERIOR_POSITION_NAME SUPERIOR_NAME SUPERIOR_USERNAME SUPERIOR_P APPROVAL_LIMIT 
----------- -------------------- --------------- --------------- -------------------------- ------------------------- --------------- ----------------- ---------- -------------- 
    120000 C1256    James   Fin. Analyst        1 Sen.Analyst    Ford   12735     782   10000 
    500000 C1256    James   Fin. Analyst        1 Sen.Analyst    Ford   12735     782   10000 
     50000 C1256    James   Fin. Analyst        1 Sen.Analyst    Ford   12735     782   10000 
     12000 C1256    James   Fin. Analyst        1 Sen.Analyst    Ford   12735     782   10000 
    120000 C1256    James   Fin. Analyst        2 Manager     Smith   329822     6218   50000 
    500000 C1256    James   Fin. Analyst        2 Manager     Smith   329822     6218   50000 
     50000 C1256    James   Fin. Analyst        2 Manager     Smith   329822     6218   50000 
    120000 C1256    James   Fin. Analyst        3 General Manager Finance Jack   23512     727   100000 
    500000 C1256    James   Fin. Analyst        3 General Manager Finance Jack   23512     727   100000 
    500000 C1256    James   Fin. Analyst        4 Chief Executive   Scott   13457     2987   500000 
+0

我只能通過prod_id作爲參數 – user75ponic

+0

您示例中的所有'prod_t'行都具有相同的'prod_id'。所以如果你只在該列上過濾,你想要什麼輸出?與'prod_id'的最高'product_amt'匹配的'pos_t'?所有匹配的任何數量(這將是相同的事情)? –

1

我想你需要的東西是這樣的:

with amounts as (
    select username, nvl(lag(product_amt) over (order by product_amt), 0) amt1, 
     product_amt amt2 
    from prod_t where username = 'C1256' and prod_id = 'BC45') 
select amt1, amt2, approval_limit, superior_name, 
    case when amt1 < approval_limit then 'PRIMARY' else 'SECONDARY' end as type 
    from amounts 
    join pos_t on amounts.username = pos_t.username and approval_limit <= amt2 
    where amt1 < 50000 and 50000 <= amt2 
    order by amt2, approval_limit desc; 


========================================================================= 


     AMT1  AMT2 APPROVAL_LIMIT SUPERIOR_NAME TYPE 
---------- ---------- -------------- ---------------- --------- 
    12000  50000   50000 Smith   PRIMARY 
    12000  50000   10000 Ford    SECONDARY 

下面的查詢顯示了list1縱隊主力審批人(S)和次級在list2,通過自己的水平進行排序。分配是根據prod_t中的值動態構建的。

with amounts as (
    select row_number() over (order by product_amt) rn, 
     nvl(lag(product_amt) over (order by product_amt), 0) amt1, 
     product_amt amt2 
    from prod_t) 
select rn, amt1, amt2, 
     (select listagg(superior_name, ',') 
       within group (order by pos_t.superior_position_level_id desc) 
      from pos_t where amt1 < approval_limit and approval_limit <= amt2) list1, 
     (select listagg(superior_name||' ('||approval_limit||')', ',') 
       within group (order by pos_t.superior_position_level_id desc) 
      from pos_t where approval_limit <= amt1) list2 
    from amounts 
    order by rn 


========================================================================= 


    RN  AMT1  AMT2 LIST1  LIST2 
------ ---------- ---------- --------- ------------------------------------------ 
    1   0  12000 Ford  
    2  12000  50000 Smith  Ford (10000) 
    3  50000  120000 Jack  Smith (50000),Ford (10000) 
    4  120000  500000 Scott  Jack (100000),Smith (50000),Ford (10000) 

是否有可能不具有和語句呢?

是的,就像這裏:

select amt1, amt2, approval_limit, superior_name, 
    case when amt1 < approval_limit then 'PRIMARY' else 'SECONDARY' end type 
    from (
    select username, nvl(lag(product_amt) over (order by product_amt), 0) amt1, 
      product_amt amt2 
     from prod_t where username='C1256' and prod_id = 'BC45') amounts 
    join pos_t on amounts.username = pos_t.username and approval_limit <= amt2 
    where amt1 < 50000 and 50000 <= amt2 
    order by amt2, approval_limit desc