是否可以在一个select语句中选择某些类型M
(字符串或枚举字段)最多N
行的有限量T
行M > N
})?
到目前为止,我已经尝试使用DBMS_RANDOM
这样,但它并不漂亮,并不能完全满足我的需求
select id from some_table
where ((type = 'A' and round(dbms_random.value(0,100)) > 75)
or (type <> 'A'))
and rownum < 1000;
编辑:
我正在处理的是一种使用数据库实现的队列。有K种不同类型的消息。 A类型的消息是低优先级的,它们每天一次或两次插入大约100k条记录。其他类型的消息具有更高的优先级并且不断插入。所以我试图实现的是以这样的方式处理这些记录:当插入类型A的消息时,其他类型的消息不会挨饿。
答案 0 :(得分:0)
我想你可以使用rownum
和union all
,但这可能会变得复杂。我认为row_number()
更适合这个目的:
select t.*
from (select id, row_number() over (partition by type order by dms_random.value()) as seqnum
from t
) t
where (type = 'A' and seqnum <= 100) and
rownum < 1000;
答案 1 :(得分:0)
随机排序不保证您获得N类型A记录和M类型非A类记录。为了保证这一点,你需要明确说明它,这意味着拆分查询以生成行号。
天真的版本会使用UNION ALL operator:
select id
from t
where type = 'A'
and rownum < N
union all
select id
from t
where type <> 'A'
and rownum < M
此方法的主要缺点是需要对表进行两次扫描。您可以使用sub-query factoring(CTE)解决此问题,但使用ROW_NUMBER()
等分析查询可能更为简单。如果您对类型进行分区,则可以使用生成的行号来独立限制:
select id
from ( select id
, type
, row_number() over (partition by case when type = 'A' then 'A'
else 'B'
end) as rnum
from t
)
where ( type = 'A' and rnum < N )
or rnum < M