Это удивительно сложная проблема, так как каждая строка должна сравниваться с каждой другой строкой для того же идентификатора, чтобы проверить наличие совпадений, и если есть несколько перекрытий, вы должны быть очень осторожны, чтобы не пересчитать их дважды.
Вот решение на основе хеша - идея состоит в том, чтобы создать хеш, содержащий все отдельные дни, в течение которых участник оставался с вами, а затем подсчитать количество элементов в нем в конце:
data have;
input id Entered left;
cards;
1 7071 7077
1 7071 7077
1 7075 7079
1 7077 7083
1 7077 7083
1 7078 7085
1 7087 7089
1 7095 7099
2 8921 8923
2 8935 8940
;
run;
data want;
length day 8;
if _n_ = 1 then do;
declare hash h();
rc = h.definekey('day');
rc = h.definedone();
end;
do until(last.id);
set have;
by id;
do day = entered to left - 1;
rc = h.add();
end;
end;
total_days = h.num_items;
rc = h.clear();
keep id total_days;
run;
Это должно быть достаточно мало для памяти, так как нужно загружать дни только для одного идентификатора за раз.
Выход с идентификатора 1 равен 20, а не 18 - вот разбивка новых днейдобавил строку за строкой, которую я сгенерировал, добавив немного логики отладки.Если это не так, укажите где:
_N_=1
7071 7072 7073 7074 7075 7076
_N_=2
No new days
_N_=3
7077 7078
_N_=4
7079 7080 7081 7082
_N_=5
No new days
_N_=6
7083 7084
_N_=7
7087 7088
_N_=8
7095 7096 7097 7098
_N_=1
8921 8922
_N_=2
8935 8936 8937 8938 8939
Если вы хотите добавить только дни для строк, соответствующих определенному условию, вы можете выбрать их, используя предложение where в операторе set, например,
set have(where = (var1 in ('value1', 'value2', ...)));