我要求根据产品数量获得批准限额。 例如。 - 如果产品数量小于10000,则获得相应的批准人。
如果产品数量大于10000且小于50000,则获得相应的批准人和10000以下的人
如果产品数量大于50000且小于100000,则获得相应的批准人和50000以下的所有人员
如果产品数量大于100000且小于500000,则获得相应的批准人和所有低于100000的人
是否有可能在不对产品数量和批准限制进行硬编码的情况下实现这一目标,这意味着它应该是动态的,因为表格中的值会发生变化。
答案 0 :(得分: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
列中的主要批准人员和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
答案 1 :(得分:1)
据我所知,你只需加入你的桌子就可以了:
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
product_amt
为12000,只返回高级职位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
或找到product_amt
的最高prod_id
并限制为此,这将获得相同的答案,但会更有效,例如:
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
,并包含金额,以便您知道它匹配的内容:< / p>
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