OK, now your last sample is a good one. I've updated my proposal (in blue) to suit the multiplicity of the data. It's actually just a matter of grouping the data. Again, as along as there is no dups by portid, firmid and myear, I think it will do what you need in a efficiently manner. Logic is the same from my previous post, average the cross join (with the convenient clause) aggregates by portid/myear and firmid/myear subtracting the current return, which is not to be considered. proc sql noprint; create table want (drop = _:) as select a.portid, a.firmid, a.myear, a.return, sum(b.sumreturn)-c.sumreturn+a.return as _sum, sum(b.cntreturn)-c.cntreturn+1 as _cnt, calculated _sum / calculated _cnt as avgreturn from return as a, (select portid, myear, sum(return) as sumreturn, count(return) as cntreturn from return group by portid, myear) as b, (select firmid, myear, sum(return) as sumreturn, count(return) as cntreturn from return group by firmid, myear) as c where a.portid ne b.portid and a.myear eq b.myear and a.firmid eq c.firmid and b.myear eq c.myear group by a.portid, a.firmid, a.myear, a.return; quit; Cheers from Portugal. Daniel Santos @ www.cgd.pt
... View more