从Oracle抽样,需要确切的结果数量(样本条款)

时间:2013-04-15 21:09:15

标签: 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&lt; 101将切断从表格底部选择的所有记录。我正在寻找的是一种从表格中提取100条记录的方法,这些记录是随机选择的,并且相当代表整个表格。请帮忙!!

3 个答案:

答案 0 :(得分:6)

借用jonearles&#39;示例表,我看到完全相同的事情(在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当然。


This Oracle article涵盖了一些抽样技巧,您可能还希望评估ora_hash方法,如果您的数据传播以及您对“代表性”的要求,则需要分层版本。要求它。

答案 1 :(得分:3)

您不能相信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

答案 2 :(得分:0)

我一直在调查类似的问题。首先,我设置了不同Stratum的样本大小。在你的情况下,它只有一个。 (&#39; 700064&#39)。因此,在使用Clause或临时表时,我这样做了:

Select DEPTID, Count(*) SAMPLE_ONE 
FROM PS_LEDGER  Sample(1)
WHERE DEPTID = '700064' 
Group By DEPTID

这会告诉您1%样本中的记录。让我们称之为TABLE_1

然后我这样做了:

Select 
Ceil (Rank() over (Partition by DEPTID Order by DBMS_RANDOM.VALUE)
            / (Select SAMPLE_ONE From TABLE_1) STRATUM_GROUP
,A.*
FROM PS_LEDGER 

制作另一张桌子。你得到的是随机样本集约。 1%的大小。

因此,如果您的原始表保存了1000条记录,那么您将获得100个随机样本集,每组中包含10个项目。

然后您可以随机选择其中一个进行测试。

不确定我是否已经很好地解释了这一点,但它对我有用。我在桌子上有168个Stratum Set,超过10Mil的记录工作得非常好。

如果您想要更多解释或者可以改进,请不要犹豫。

此致

相关问题