【问题标题】:Select random sample of N rows from Oracle SQL query result从 Oracle SQL 查询结果中选择 N 行的随机样本
【发布时间】:2020-12-27 03:06:35
【问题描述】:

我想减少从查询结果中导出的行数。我没有运气适应发布在on this thread 上的公认解决方案。

我的查询如下所示:

select
    round((to_date('2019-12-31') - date_birth) / 365, 0) as age
from
    personal_info a
where
    exists
        (
        select person_id b from credit_info where credit_type = 'C' and a.person_id = b.person_id
        )
;

这个查询返回的行数比我需要的多,所以我想知道是否有办法使用sample() 从这个查询产生的许多行中选择固定数量的行(不是百分比)。

【问题讨论】:

    标签: sql oracle random


    【解决方案1】:

    您可以通过随机排序然后获取前 N 行来对数据进行采样。

    DBMS_RANDOM.RANDOM

    select round((to_date('2019-12-31') - date_birth) / 365, 0) as age
    From personal_info a 
    where exists ( select person_id b from credit_info where credit_type = 'C' and a.person_id = b.person_id )
    Order by DBMS_RANDOM.RANDOM
    Fetch first 250 Rows
    

    编辑:适用于 oracle 11g 及之前的版本

    Select * from (
        select round((to_date('2019-12-31') - date_birth) / 365, 0) as age
        From personal_info a 
        where exists ( select person_id b from credit_info where credit_type = 'C' and a.person_id = b.person_id )
        Order by DBMS_RANDOM.RANDOM
    )
    Where rownum< 250
    

    【讨论】:

    • 我认为 fetch frist N rows 在我使用的 Oracle 版本上不可用(我认为它是 10g)。有解决办法吗?
    【解决方案2】:

    如果你使用的是12C,可以使用下面的行限制子句

    select
        round((to_date('2019-12-31') - date_birth) / 365, 0) as age
    from
        personal_info a
    where
        exists
            (
            select person_id b from credit_info where credit_type = 'C' and a.person_id = b.person_id
            ) 
    FETCH NEXT 5 ROWS ONLY;
    

    你可以使用任何你想要的数字来代替 5。

    【讨论】:

    • 不幸的是,据我所知,除了您在上面发布的线程链接之外,在 10g 中没有好的方法可以做到这一点。为了采用这一点,您必须确保在内部查询中使用 order by,否则它将不起作用。但问题是内部查询会进行全表扫描,但就输出而言,您将能够限制行数。希望这会有所帮助!
    【解决方案3】:

    您可以使用fetch first 返回固定数量的行。只需添加:

    fetch first 100 rows
    

    到您的查询结束。

    如果您希望以某种方式对这些样本进行抽样,则需要说明您希望采用哪种类型的抽样。

    【讨论】:

    • 我想打乱结果并获取前 N 行。 fetch 做得很好,但我必须重新索引行 ID,对吗?有没有办法在这里使用sample()
    猜你喜欢
    • 2010-10-18
    • 2016-05-21
    • 1970-01-01
    • 2010-11-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-13
    • 2010-10-25
    相关资源
    最近更新 更多