在 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);
我需要从数据仓库中的不同表中提取大量数据,比如 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);