笛卡尔连接 SAS Proc SQL

Cartesian Join SAS Proc SQL

我有两个数据集,如下所示:

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;

我会这样处理:

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;

这不需要辅助 table cartesian,这可能会更快。 sales(store, week) 上的索引肯定会加快查询速度。

我将推荐一种替代方法,该方法涉及从 DATES 数据集创建格式,然后使用 proc summary 中的 completetypespreloadfmt 输出所有观察结果。

这假设所有必需的日期都出现在 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;