use*_*134 5 oracle sample random-sample
我试图从Peoplesoft数据库中随机抽取一个人口样本.在线搜索让我认为select语句的Sample子句可能是我们使用的可行选项,但是我无法理解Sample子句如何确定返回的样本数.我查看了这里找到的oracle文档:http: //docs.oracle.com/cd/E11882_01/server.112/e26088/statements_10002.htm#i2065953
但上述参考仅讨论了用于创建示例的语法.我的问题的原因是我需要了解样本百分比如何确定返回的样本大小.似乎它将随机数应用于您要求的百分比,然后使用种子数来计算每个"n"记录.我们的要求是我们提取一定数量的样本,例如,它们是随机选择的,并且它们代表整个表格(或者至少是我们用过滤器选择的数据分组)
如果我需要大约100个项目的样本,在10200个项目的人口中,我可以使用此声明:
SELECT * FROM PS_LEDGER SAMPLE(1) --1 % of my total population
WHERE DEPTID = '700064' 
但是,我们需要提取一定数量的样本(在这种情况下为100),这样我就可以选择一个样本大小,几乎总是返回超过我需要的数量,然后将其修剪下来IE
SELECT Count(*) FROM PS_LEDGER SAMPLE(2.5) --this percent must always give > 100 items
WHERE DEPTID = '700064' and rownum < 101
我担心的是,我的样本不能统一代表整个人口.例如,如果示例函数在创建自己的随机生成的种子后拉动每个N记录,则选择rownum <101将切断从表格底部选择的所有记录.我正在寻找的是一种从表格中提取100条记录的方法,这些记录是随机选择的,并且相当代表整个表格.请帮忙!!
借用jonearles的示例表,我看到完全相同的东西(在OEL开发人员图像上的11gR2中),通常会获得a严重偏向的值1; 小样本我有时根本看不到.我在评论中提到了额外的随机化/限制步骤:
select a, count(*) from (
    select * from test1 sample (1)
    order by dbms_random.value
)
where rownum < 101
group by a;
......我得到了三次跑步:
         A   COUNT(*)
---------- ----------
         1         71
         2         29
         A   COUNT(*)
---------- ----------
         1        100
         A   COUNT(*)
---------- ----------
         1         64
         2         36
是的,100%真的回来了,就像1第二轮一样.倾斜本身似乎相当随机.我尝试使用block修饰符似乎没什么区别,也许令人惊讶 - 我可能认为在这种情况下它会变得更糟.
对于小样本来说,这可能会更慢,因为它必须达到整个表格; 但确实给我提供了相当一致的分裂:
select a, count(*) from (
    select a, b from (
        select a, b, row_number() over (order by dbms_random.value) as rn
        from test1
    )
    where rn < 101
)
group by a;
我得到了三次:
         A   COUNT(*)
---------- ----------
         1         48
         2         52
         A   COUNT(*)
---------- ----------
         1         57
         2         43
         A   COUNT(*)
---------- ----------
         1         49
         2         51
......看起来更健康一点 YMMV当然.
这篇Oracle文章介绍了一些抽样技术,您可能也希望评估该ora_hash方法,如果您的数据传播以及您对"代表性"的要求需要分层版本.
您不能相信SAMPLE会从表中返回真正随机的行集。该算法似乎是基于桌子的物理属性。
create table test1(a number, b char(2000));
--Insert 10K fat records.  A is always 1.
insert into test1 select 1, level from dual connect by level <= 10000;
--Insert 10K skinny records.  A is always 2.
insert into test1 select 2, null from dual connect by level <= 10000;
--Select about 10 rows.
select * from test1 sample (0.1) order by a;
多次运行最后一个查询,您几乎不会看到任何 2。如果您按字节而不是行进行测量,这可能是一个准确的示例。
这是数据倾斜的一个极端例子,但我认为这足以表明它并RANDOM没有按照手册暗示的方式工作。正如其他人所建议的那样,您可能会想要这样做ORDER BY DBMS_RANDOM.VALUE。
| 归档时间: | 
 | 
| 查看次数: | 7817 次 | 
| 最近记录: |