Re: [SQL ] 滚动计算并回传

楼主: linec153 (LINEC)   2020-11-20 18:42:23
以下仅供参考
因为问题叙述还不够完善,我仅就能理解的部分提供建议
这个问题牵涉到大数据与full table scan
所以我会先考虑复杂度的估计
我估算的复杂度如下,因为不是很会估,如果有算错请高手能不吝指正
两个档互串,有两个比对变量,又是使用between作范围式比对
我估的比对次数为
240万*1600万*1600万=614400000万
但如果资料是6年并在一起,依照需求会有很多无效比对
还有,table a 重点是要知道 date+doctor 的组合,所以我估算每年平均40万笔资料
去重复假设变30万笔
那么,估算切一年算一次的次数就是
30万*(1600万/6*2)*(1600万/6*2)*6(年)=51136020万
至少差12倍
=======
所以,建议至少一年切一次,每年算一次
SAS里,先把原始资料切年度做成档案,然后再用SQL执行计算
想一句写完,看起来很帅,但不见得跑得快
我写个范例表示一下我的概念:
/*先依照年分切档案*/
data table_a_2019 table_a_2018;
set table_a;
if year(prescriptionBeginDate)=2019 then output table_a_2019;
if year(prescriptionBeginDate)=2018 then output table_a_2018;
keep prescriptionBeginDate DOCTOR;
run;
proc sort data=table_a_2019 nodup;
by DOCTOR prescriptionBeginDate ;
proc sort data=table_a_2018 nodup;
by DOCTOR prescriptionBeginDate ;
run;
data table_b_2019 table_b_2018;
set table_b;
if 2018<=year(prescriptiondate)<=2019 then output table_b_2019;
if 2017<=year(prescriptiondate)<=2018 then output table_b_2018;
run;
/*再用SAS分年度计算*/
proc sql;
select distinct a.*, count(distinct b.SID) as service_volume
from table_a_2019 as a, table_b_2019 as b
where a.Doctor=b.Doctor and
b.prescriptiondate between a.prescriptionBeginDate and intnx('year', a.PrescriptionBeginDate, -1, 'same')
;
quit;
如果切半年算一次
我估的复杂度是
15万*(1600万/12*2)*(1600万/12*2)*12(0.5年)=12832020万
跟原始差47倍,省更多时间
也就是要用 空间 换取时间
以上分享
※ 引述《Wengboyu ( )》之铭言:
: 数据库名称:SAS SQL
: 数据库版本:9.4
: 内容/问题描述:
: 我有table a和b
: table a
: date SID doctor
: 2019/1/1 a jack
: 2019/1/2 a jack
: 2019/1/3 a jack
: 2019/2/1 b ben
: 2019/2/2 b ben
: 2019/2/3 b ben
: ...
: 2019/2/15 b mark
: 2019/2/16 b mark
: 2019/2/17 b mark
: table b
: date SID doctor
: 2018/1/1 a jack
: 2018/1/2 b jack
: 2018/1/3 c jack
: 2018/1/15 a jack
: 2018/1/31 a ben
: 2018/3/1 b ben
: 2018/3/1 c mark
: 2018/4/16 d mark
: 2018/4/21 c mark
: 我要得到下面的结果
: table c
: date SID doctor doctor_service_volume
: 2019/1/1 a jack 3
: 2019/1/2 a jack 3
: 2019/1/3 a jack 2
: 2019/2/1 b ben 1
: 2019/2/2 b ben 1
: 2019/2/3 b ben 1
: ...
: 2019/2/15 b mark 2
: 2019/2/16 b mark 2
: 2019/2/17 b mark 2
: 我要计算table a每一笔,a.doctor在a.date过去一年内收过多少病人(不重复)
: table b是处方签资料
: 例如:
: first row in table a
: date SID doctor
: 2019/1/1 a jack
: 我就要从table b中去找docor jack在a.date和(a.date - 1 year)间
: 收了多少不重复的病人
: table b doctor jack 在2018/1/1 ~ 2019/1/1开过处方签的病人
: date SID doctor
: 2018/1/1 a jack
: 2018/1/2 b jack
: 2018/1/3 c jack
: 2018/1/15 a jack (重复)
: 所以a.doctor_service_volume = 3
: 我自己写的code如下
: Proc sql;
: create table want as select
: a.*, (select count(distinct b.SID)
: from
: dataset a, dataset b
: where
: a.DoctorID = b.DoctorID and a.DoctorID is not missing and
: b.prescriptiondate between a.prescriptionBeginDate and
: intnx('year', a.PrescriptionBeginDate, -1, 'same'))
: as service_volume
: from
: dataset a, dataset b;
: quit;
: 因为跑很久,我不太确定这样写是不是可以得到我要的结果..
: table a 有240万笔,b有1600万笔
: 如果大家要测试自己code写得对不对,会怎么弄?

Links booklink

Contact Us: admin [ a t ] ucptt.com