I assume your data are already sorted by ACCNO/TRANDATE. True, sorting by descending date (within each ACCNO) would allow you to take the first 20 of each ACCNO, a relatively straightforward process. But sorting is expensive, and you might need to re-sort the results by ascending date.
So here is a two pass process (passing through each ACCNO twice, but in the original order:
data transfer (drop=_:);
set transactions (in=firstpass)
transactions (in=secondpass) ;
by accnow;
_n1 + firstpass;
_n2 + secondpass;
if secondpass=1 and _n2>= _n1-20;
run;
Even though you pass through the entire dataset twice, it won't require twice the data-reading resources, because the SET statement interleaves the firstpass for a given ACCNO with the secondpass for the same ACCNO. Since the most recently read observations (from firstpass) will be cached in memory, they will therefore be available to the secondpass without rereading data from the storage device.
... View more