SAS中文论坛

标题: 请教一个从两个表提取数据的问题 [打印本页]

作者: shiyiming    时间: 2011-4-1 12:45
标题: 请教一个从两个表提取数据的问题
有两个数据表a、b,现在要根据表b的记录,从表a中提取数据,要求根据表b的每一条记录取出变量date当天以及前后三天的数据(code相同)。

data a;
input ID$ Date yymmdd8. Num;
format Date yymmdd10.;
cards;
001 08-07-01 100
001 08-07-02 200
001 08-07-03 100
001 08-07-04 900
001 08-07-05 100
001 08-07-06 800
001 08-07-07 100
001 08-07-08 200
001 08-07-09 100
001 08-07-10 100
001 08-07-11 500
001 08-07-12 100
002 08-07-01 100
002 08-07-02 200
002 08-07-03 100
002 08-07-04 900
002 08-07-05 100
002 08-07-06 800
002 08-07-07 100
002 08-07-08 200
002 08-07-09 100
002 08-07-10 100
002 08-07-11 500
002 08-07-12 100
;


data b;
input ID$ Date yymmdd8. company;
format Date yymmdd10.;
cards;
001 08-07-05 1
001 08-07-07 2
002 08-07-04 2
002 08-07-06 3
001 08-07-09 2
;

我需要的结果如下:
ID  Date      Num  company
001 08-07-02 200 1
001 08-07-03 100 1
001 08-07-04 900 1
001 08-07-05 100 1
001 08-07-06 800 1
001 08-07-07 100 1
001 08-07-08 200 1
001 08-07-04 900 2
001 08-07-05 100 2
001 08-07-06 800 2
001 08-07-07 100 2
001 08-07-08 200 2
001 08-07-09 100 2
001 08-07-10 100 2
002 08-07-01 100 2
002 08-07-02 200 2
002 08-07-03 100 2
002 08-07-04 900 2
002 08-07-05 100 2
002 08-07-06 800 2
002 08-07-07 100 2
002 08-07-03 100 3
002 08-07-04 900 3
002 08-07-05 100 3
002 08-07-06 800 3
002 08-07-07 100 3
002 08-07-08 200 3
002 08-07-09 100 3
002 08-07-06 800 2
002 08-07-07 100 2
002 08-07-08 200 2
002 08-07-09 100 2
002 08-07-10 100 2
002 08-07-11 500 2
002 08-07-12 100 2

不知道说清楚了没有,谢谢 <!-- s:D --><img src="{SMILIES_PATH}/icon_biggrin.gif" alt=":D" title="Very Happy" /><!-- s:D -->
作者: Qiong    时间: 2011-4-1 13:37
标题: Re: 请教一个从两个表提取数据的问题
[code:cact5um8]
proc sql;
create table v as select a&#46;*,b&#46;company
from b as b
left join a  as a
on a&#46;ID=b&#46;id  and b&#46;date+3&gt;=a&#46;date&gt;=b&#46;date-3
order by id, company,date;
quit;[/code:cact5um8]
作者: shiyiming    时间: 2011-4-1 22:59
标题: Re: 请教一个从两个表提取数据的问题
[quote=&quot;vicky1020&quot;:62d7hcyf][code:62d7hcyf]
proc sql;
create table v as select a&#46;*,b&#46;company
from b as b
left join a as a
on a&#46;ID=b&#46;id and b&#46;date+3&gt;=a&#46;date&gt;=b&#46;date-3
order by id, company,date;
quit;[/code:62d7hcyf][/quote:62d7hcyf]

谢谢,不过有点小问题,日期可能不是连续的,比如周日刚好没有记录。
作者: Qiong    时间: 2011-4-2 09:40
标题: Re: 请教一个从两个表提取数据的问题
没明白,为什么要连续?
是周日算休息,然后取前后3个工作日的record?
作者: shiyiming    时间: 2011-4-2 10:26
标题: Re: 请教一个从两个表提取数据的问题
[quote=&quot;vicky1020&quot;:346h1kuq]没明白,为什么要连续?
是周日算休息,然后取前后3个工作日的record?[/quote:346h1kuq]


b.date+3&gt;=a.date&gt;=b.date-3要日期是连续的能保证表B的没条记录可以表A中取出7条来。

比如,如果A表的日期是(08-07-08没有数据 ):
001 08-07-01 100
001 08-07-02 200
001 08-07-03 100
001 08-07-04 900
001 08-07-05 100
001 08-07-06 800
001 08-07-07 100
001 08-07-09 200
001 08-07-10 100
001 08-07-11 100
001 08-07-12 500
B表的数据时
001 08-07-05 1
取出来的数据应该是
001 08-07-02 200
001 08-07-03 100
001 08-07-04 900
001 08-07-05 100
001 08-07-06 800
001 08-07-07 100
001 08-07-09 200
(08-07-08没有,再下一天就是08-07-09了  )
作者: Qiong    时间: 2011-4-2 13:57
标题: Re: 请教一个从两个表提取数据的问题
那你应该给一个不全的data呀~~
如果每周固定某天没有数据,比如周日没有~~~
proc sql;
create table v as select a.*,b.company,b.date as date_mid
from b as b
left join a as a
on a.ID=b.id and b.date+3+(5&lt;=weekday(b.date)&lt;=7)&gt;=a.date&gt;=b.date-3-(2&lt;=weekday(b.date)&lt;=4)
order by id,date_mid, company,date;
quit;

btw, 08-07-08是周二
作者: shiyiming    时间: 2011-4-2 15:14
标题: Re: 请教一个从两个表提取数据的问题
恩,谢谢,我开始没把问题描述清楚!
现在关键是空缺的日期不是很有规律,节假日什么的都是空的。
作者: Qiong    时间: 2011-4-2 15:24
标题: Re: 请教一个从两个表提取数据的问题
土人土法

proc sql;
create table vtemp  as select a.*,b.company,b.date as date_mid
from b as b
left join a as a
on a.ID=b.id ;
quit;

%macro a(yymmdd,id,lag=3);

%let con= %str(id=&quot;&amp;id&quot; and date_mid=&amp;yymmdd.);

proc sql;
create table v1 as select *
from vtemp  where date&lt; &amp;yymmdd. and &amp;con.
order by date descending;
create table v2 as select *
from vtemp  where date&gt; &amp;yymmdd. and &amp;con.
order by date ascending ;
create table v3 as select *
from vtemp  where date= &amp;yymmdd. and &amp;con.;
quit;

data vv_final ;
set vv_final v1(obs=&amp;lag.) v3(obs=1) v2 (obs=&amp;lag.) ;
run;

%mend a;

data vv_final;
set vtemp(obs=0);
data _null_;
set b ;
call execute('%a('||date||','||id||');');
call execute('run;');
run;  

应该有更fancy的方法
作者: shiyiming    时间: 2011-4-2 15:59
标题: Re: 请教一个从两个表提取数据的问题
多谢,程序虽然复杂一点,但是管用,问题是第一个left join会导致数据量奇大无比 <!-- s:D --><img src="{SMILIES_PATH}/icon_biggrin.gif" alt=":D" title="Very Happy" /><!-- s:D -->  <!-- s:D --><img src="{SMILIES_PATH}/icon_biggrin.gif" alt=":D" title="Very Happy" /><!-- s:D -->
作者: shiyiming    时间: 2011-4-2 16:54
标题: Re: 请教一个从两个表提取数据的问题
[quote=&quot;vicky1020&quot;:pdhu8iho]土人土法[/quote:pdhu8iho]
vicky姐自谦啊,俺菜拿data步捣鼓了半天没搞出来捏...
作者: Qiong    时间: 2011-4-2 17:11
标题: Re: 请教一个从两个表提取数据的问题
[quote:outjqvuh]由 ganshenme » 2011年 4月 2日 周六 3:59 pm

多谢,程序虽然复杂一点,但是管用,问题是第一个left join会导致数据量奇大无比   [/quote:outjqvuh]

不生成vtemp

%macro a(yymmdd,id,company,lag=3);
  
proc sql;
create table v1 as select *
from a where &amp;yymmdd. -10&lt;= date&lt; &amp;yymmdd. and id=&quot;&amp;id&quot;
order by date descending;
create table  v2 as select *
from a where  &amp;yymmdd.+10 &gt;= date&gt; &amp;yymmdd. and  id=&quot;&amp;id&quot;
order by date ascending ;
create table   v3 as select *
from a where date= &amp;yymmdd. and id=&quot;&amp;id&quot; ;
quit;

data vv_final ;
set vv_final(in=a) v1(obs=&amp;lag.) v3(obs=1) v2 (obs=&amp;lag.) ;
if not a then campany=&quot;&amp;company.&quot;;
run;

%mend a;

data vv_final;
set a(obs=0);
data _null_;
set b ;
call execute('%a('||date||','||id||','||company||');');
call execute('run;');
run;
作者: Qiong    时间: 2011-4-2 17:29
标题: Re: 请教一个从两个表提取数据的问题
不知道你的a到底多大?如果还是太慢,run的太费劲的话,试试在a里对id,date建index,macro里面应该会快点。
作者: shiyiming    时间: 2011-4-6 09:23
标题: Re: 请教一个从两个表提取数据的问题
谢谢vicky!
我的表A有170万条数据,表B有6000多条记录,lag=125,用了13个小时跑完,不知道问题出在哪里 <!-- s:? --><img src="{SMILIES_PATH}/icon_confused.gif" alt=":?" title="Confused" /><!-- s:? -->
作者: Qiong    时间: 2011-4-6 09:52
标题: Re: 请教一个从两个表提取数据的问题
汗。。。。这个vtemp当然super super super 大了。。。。
对a里面加个index,然后把code里面第一层的选择放宽到lag+8,这个8是中国最长的长假天数
重新run应该不用那么久。。。
再不放心的话,先run data b的一百条,测试下速度。

btw,好奇什么分析要天数这么精确,125天和124天有差么?
作者: shiyiming    时间: 2011-4-6 10:41
标题: Re: 请教一个从两个表提取数据的问题
我这里给数据只是一个简单的例子,实际数据变量会多一些。

我们是要分析某个时间(表b)前后一段时间(表a)的结果,所以用到的lag会比较大,当然是125还是124没有很大关系。

另外如果lag=125的话,code里面第一层的选择可能会达到200.

如果只run data b的100条,几分钟就能完成,一条实际用时大概在5秒,但是到后面就比较慢了,一条用时会达到10秒以上。
作者: Qiong    时间: 2011-4-6 11:03
标题: Re: 请教一个从两个表提取数据的问题
missing的天数很多么?不然为什么要放宽到200这么大?

越来越慢的原因可能是vv_final 越来越大,试试proc append 代替data 步
作者: shiyiming    时间: 2011-4-6 11:27
标题: Re: 请教一个从两个表提取数据的问题
通常一周的实际lag是5天,lag=125就相当于25周,至少175天,加上别的假期啥的,需要放宽到200~

我在试试看,多谢 <!-- s:D --><img src="{SMILIES_PATH}/icon_biggrin.gif" alt=":D" title="Very Happy" /><!-- s:D -->




欢迎光临 SAS中文论坛 (https://mysas.net/forum/) Powered by Discuz! X3.2