在 sas 中使用 proc sql 从仓库(oracle 引擎)提取数据时进行简单随机抽样

simple random sampling while pulling data from warehouse(oracle engine) using proc sql in sas

我需要从数据仓库中的不同表中提取大量数据,比如 600-700 个变量...现在原始形式的数据集很容易达到 150 gigs - 79 MM 行并用于我的分析目的我只需要一百万行...如何通过对行进行简单的随机抽样,直接使用 proc sql 从仓库中提取数据。

以下代码无法运行,因为 oracle 不支持 ranuni

    proc sql outobs =1000000;
    select * from connection to oracle(
    select * from tbl1 order by ranuni(12345);
    quit;

你建议我怎么做

使用DBMS_RANDOM包对记录进行排序,然后使用行限制子句限制到所需的样本大小

dbms_random.value函数为table中的所有行获取一个介于0和1之间的随机数,我们按随机值的升序排序。

以下是生成您确定的样本集的方法:

    SELECT
    *
FROM
    (
        SELECT
            *
        FROM
            tbl1
        ORDER BY dbms_random.value
    )
FETCH FIRST 1000000 ROWS ONLY;

为了使用示例架构 table、emp 进行演示,我们对 4 条记录进行了采样:

   SCOTT@DEV> SELECT
  2      empno,
  3      rnd_val
  4  FROM
  5      (
  6          SELECT
  7              empno,
  8              dbms_random.value rnd_val
  9          FROM
 10              emp
 11          ORDER BY rnd_val
 12      )
 13  FETCH FIRST 4 ROWS ONLY;
EMPNO  RND_VAL
7698   0.06857749035643605682648168347885993709
7934   0.07529612360785920635181751566833986766
7902   0.13618520865865754766175030040204331697
7654   0.14056380246495282237607922497308953768


SCOTT@DEV> SELECT
  2      empno,
  3      rnd_val
  4  FROM
  5      (
  6          SELECT
  7              empno,
  8              dbms_random.value rnd_val
  9          FROM
 10              emp
 11          ORDER BY rnd_val
 12      )
 13  FETCH FIRST 4 ROWS ONLY;
EMPNO  RND_VAL
7839   0.00430658806761508024693197916281775492
7499   0.02188116061148367312927392115186317884
7782   0.10606515700372416131060633064729870016
7788   0.27865276349549877512032787966777990909

在上面的示例中,请注意 empno 在执行 SQL*Plus 命令期间发生了显着变化。

性能可能与您描述的行数有关。


编辑:

table 尺寸大约为 150 gigs - 79 MM,任何排序都会很痛苦。

如果 table 有一个基于递增 1 的序列的代理键,我们可以采用基于该键选择每第 n 条记录的方法。

例如

    --scenario n = 3000

 FROM
    tbl1
WHERE
    mod(table_id, 3000) = 0;

这种方法不会使用索引(除非创建了基于函数的索引),但至少我们不会对这种大小的数据集执行排序。

我用 table 执行了一个解释计划,它有近 8000 万条记录,它确实执行了完整的 table 扫描(条件强制执行此操作而没有基于函数的索引)但这看起来站得住脚。

None 发布的答案或评论帮助了我的事业,它可以但我们有 87 MM 行

现在我想在 sas 的帮助下得到答案:这就是我所做的:而且它有效。谢谢大家!

    libname dwh path username pwd;
    proc sql;
    create table sample as
    (select 
     <all the variables>, ranuni(any arbitrary seed)
     from dwh.<all the tables>
     <bunch of where conditions goes here>);
     quit);