我有两个看起来像这样的数据集:
data sales;
format week date9.;
input store $ week date9. sales;
cards;
A 01JAN2014 200
A 08JAN2014 500
A 22JAN2014 200
B 01JAN2014 100
B 08JAN2014 200
B 15JAN2014 200
;
run;
data dates;
format week date9.;
input week date9.;
cards;
01JAN2014
08JAN2014
15JAN2014
22JAN2014
29JAN2014
;
run;
这些是数据库中非常大的表的小例子。我想使用proc sql步骤加入它们,以便每个位置都存在所有日期(如果没有销售则缺少值)。我已经创建了商店和周的笛卡尔连接以产生所需的结果,但是当我尝试查询大量数据时,这种方法被证明是非常低效的。我知道有更好的方法可以做到这一点,但无法得到它。下面是我的尝试......澄清一下,full_sales数据集是所需的输出,我只需要一种更有效的方法来实现它。感谢。
proc sql;
create table cartesian as
select distinct sales.store, dates.week
from sales, dates
order by 1,2;
quit;
proc sql;
create table full_sales as
select cartesian.store,
cartesian.week,
sales.sales
from cartesian
left join sales
on cartesian.store=sales.store and
cartesian.week=sales.week
order by 1,2
;
quit;
答案 0 :(得分:2)
我会这样做:
proc sql;
create table full_sales as
select s.store, w.week, ssa.sales
from (select distinct store from sales) s cross join
dates w left join
sales sa
on s.store = sa.store and
w.week = sa.week
order by 1,2
;
quit;
这不需要辅助表cartesian
,这可能更快。 sales(store, week)
上的索引肯定会加快查询速度。
答案 1 :(得分:2)
我会推荐一种替代方法,包括从DATES数据集创建格式,然后使用completetypes
中的preloadfmt
和proc summary
输出所有观察结果。
这假设所有必需的日期都出现在DATES数据集中(即SALES中没有日期没有出现在DATES中)。这可能比使用proc sql
更快。
我在最后添加了一个步骤,将格式更改回标准date9.
,因为人们可能会遇到使用用户定义的wk_fmt.
格式打开数据集的问题。
data sales;
format week date9.;
input store $ week :date9. sales;
cards;
A 01JAN2014 200
A 08JAN2014 500
A 22JAN2014 200
B 01JAN2014 100
B 08JAN2014 200
B 15JAN2014 200
;
run;
data dates;
format week date9.;
input week :date9.;
cards;
01JAN2014
08JAN2014
15JAN2014
22JAN2014
29JAN2014
;
run;
/* create dataset with format details */
data week_format;
set dates;
rename week = start;
retain fmtname 'wk_fmt' type 'N';
label = vvalue(week);
run;
/* load format from previous dataset */
proc format cntlin=week_format;
run;
/* create table of all combinations of store and dates */
proc summary data = sales nway completetypes;
class store;
class week / preloadfmt;
format week wk_fmt.;
id sales;
output out=want (drop=_:);
run;
/* change format back to date9. */
proc datasets lib=work nodetails nolist;
modify want;
format week date9.;
quit;