[英]oracle sql select/set rownumber limitation differently for different group in one data set
I have a table have 4 columns: customer, product_id, score, tag there are 2 value in tag column 'new' and 'old' 我有一个表,该表有4列:customer,product_id,score,tag在tag列“ new”和“ old”中有2个值
for each customer has both product_id from 'new' and 'old' tag(number varies) for each customer, we rank product_id based on score and tag we have total limitation for the number of product for each customer. 对于每个客户,每个客户都有'new'和'old'标签的product_id(数量各不相同),我们根据得分和标签对product_id进行排名,我们对每个客户的产品数量有总限制。 called it 'n_prod'
称之为“ n_prod”
I hope to select (2/3 *n_prod) product_id from 'old' tag and (1/3*n_prod) product for 'new' tag for each customer eg if we need to choose 6 product, hope having 4 from 'old' tag (top 4 based on the score), and have 2 from 'new' tag (the top 2 based on score) 我希望为每个客户从“旧”标签中选择(2/3 * n_prod)product_id,为“新”标签中选择(1/3 * n_prod)产品,例如,如果我们需要选择6种产品,希望从“旧”标签中选择4种标签(基于得分的前4名),以及“新”标签中的2个(基于得分的前2名)
I am able to create a column called 'rn' use the following command to rank product_id based on each customer and tag 我能够创建一个名为“ rn”的列,使用以下命令根据每个客户和标签对product_id进行排名
select customer, product_id, score, tag
, row_number()over(partition by customer,tag, order by score desc) as rn
from table
the number of limitation is different for different group: tried this but does not work: 限制数量对于不同的组是不同的:尝试过此方法,但不起作用:
with tep as
(select customer, product_id, score, tag
, row_number()over(partition by customer,tag, order by score desc) as rn
from table)
select tep.*
from tep
where ( case
when tag='new' then rn<= round(n_prod*0.33,0)
else then rn<= round(n_prod*0.66,0)
end
);
could I combine 'where' with 'case when ' or 'if else'? 我可以将“ where”和“ case when”或“ if else”组合在一起吗?
restate the expected result: I hope to select (2/3 *n_prod) product_id from 'old' tag and (1/3*n_prod) product for 'new' tag for each customer eg if we need to choose 6 product, hope having 4 from 'old' tag (top 4 based on the score), and have 2 from 'new' tag (the top 2 based on score) 重申预期结果:我希望为每个客户从“旧”标签中选择(2/3 * n_prod)product_id,为“新”标签中选择(1/3 * n_prod)产品,例如,如果我们需要选择6种产品,希望4个来自“旧”标签(基于得分排名前4位),还有2个来自“新”标签(基于得分排名前2位)
It's hard to be sure without data, but I think you just need to use Boolean logic in your where clause: 很难确定没有数据,但是我认为您只需要在where子句中使用布尔逻辑:
...
select tep.*
from tep
where (tag = 'new' and rn <= round(n_prod*0.33))
or (tag = 'old' and rn <= round(n_prod*0.66));
Quick demo with some made-up data in another CTE, and n_prod
as a bind variable: 使用另一个CTE中的一些
n_prod
数据进行快速演示,并将n_prod
作为绑定变量:
var n_prod number;
exec :n_prod := 6;
with your_table (customer, product_id, score, tag) as (
select 1234, 2345, level, 'old' from dual connect by level <= 10
union all select 1234, 2345, level, 'new' from dual connect by level <= 10
),
tep as
(select customer, product_id, score, tag
, row_number()over(partition by customer,tag order by score desc) as rn
from your_table)
select tep.*
from tep
where (tag = 'new' and rn <= round(:n_prod*0.33))
or (tag = 'old' and rn <= round(:n_prod*0.66));
CUSTOMER PRODUCT_ID SCORE TAG RN
---------- ---------- ---------- --- ----------
1234 2345 10 new 1
1234 2345 9 new 2
1234 2345 10 old 1
1234 2345 9 old 2
1234 2345 8 old 3
1234 2345 7 old 4
Incidentally, you probably need to increase the number of digits in the multipliers you're using for large values of n_prod
. 顺便说一句,您可能需要增加用于
n_prod
较大值的n_prod
。 With 0.33 and 0.66 the total number of rows returned starts to go wrong after... er... 28. ( round(28*.33)
is 9; round(28*.66)
is 18; so the total is 27 instead of 28. Using 0.333 and 0.666 seems to be safe until 253; using 0.3333 and 0.6666 until 2503; etc. 在... er ... 28之后,使用0.33和0.66时,返回的总行数开始出错。(
round(28*.33)
为9; round(28*.66)
为18;因此总数为27直到253,使用0.333和0.666似乎是安全的;直到2503使用0.3333和0.6666才是安全的;等等。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.