Cartesian加入SAS Proc SQL

时间:2015-04-02 02:10:04

标签: sql join sas cartesian

我有两个看起来像这样的数据集:

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;

2 个答案:

答案 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中的preloadfmtproc 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;
相关问题