Вставьте новый столбец с итеративным значением в каждую уникальную строку таблицы, используя pro c sql - PullRequest
0 голосов
/ 24 апреля 2020

Могу ли я узнать, есть ли способ вставить новый столбец с итеративным значением в каждую уникальную строку в таблице?

Пример:

ТАБЛИЦА ЕСТЬ

ID  name
1   John
2   Matt
3   Pete

Сейчас , У меня есть счетчик = 3, и я хочу добавить каждое значение счетчика до 3 к каждому уникальному идентификатору в таблице HAVE.

TABLE WANT

ID name count
1  John 1
1  John 2
1  John 3
2  Matt 1
2  Matt 2
2  Matt 3
3  Pete 1
3  Pete 2
3  Pete 3

Я могу сделать это, используя шаг данных используя комбинацию by и first.var:

data want;
  set have;
    by ID;
  if first.ID then do;
    do i = 1 to count;
      output;
    end;
  end;
run;

Моя главная проблема здесь - это время выполнения, шаг данных, обрабатывающий набор данных последовательно и выполнение которого может занять некоторое время. Я хочу знать, можно ли это сделать с помощью pro c sql?

Ответы [ 2 ]

1 голос
/ 24 апреля 2020

Это не может быть сделано особенно легко proc sql с использованием встроенных функций. Одним из решений является, если у вас есть какой-то счет или таблица чисел. Тогда вы можете просто сделать:

select id, t.name, n.n
from t join
     numbers n
     on n.n <= :counter;

На самом деле, если ваши идентификаторы последовательны без пробелов (как в вашем примере), вы можете использовать самостоятельное соединение:

select t.id, t.name, n.id as count
from t join
     t n
     on n.id <= :counter;

Если вы знаете значение c, вы можете создать запрос union all:

select id, name, 1 as count from t
union all
select id, name, 2 as count from t
union all
select id, name, 3 as count from t;

Современный SQL теперь имеет конструкции, которые упрощают этот процесс (например, оконные функции и рекурсивные CTE). Тем не менее, они не доступны непосредственно в proc sql.

0 голосов
/ 25 апреля 2020

Результирующий набор является внешним объединением и будет содержать N 2 строк, если имеется N различных строк.

Пример:

SASHELP.CLASS имеет 19 отдельные строки, и каждая строка будет иметь 18 повторов, в результате чего будет 19 ** 2 или 361 ряд. 1011 *

data class;
  set sashelp.class;
run;

proc sql; 
* monotonic() trusted by Richard for this create/select only ;
* commented out for fear of mono (pun intended);
* create table indexes as 
  select index from
  ( select distinct *, monotonic() as index from class);

  * one mark per distinct row;
  create table distinct_marks(keep=mark) as
  select distinct *, 1 as mark from class;

* create table of traditionally computed monotonic indexes;
data indexes(keep=index);
  set distinct_marks;
  index + 1;
run;

proc sql;
  create table want as
  select 
    self.*, 
    each.index 
  from 
    class as self 
  cross join 
    indexes as each
  ;
quit;

Сравните вышеприведенное с вашим первоначальным подходом

proc sql noprint;
  select count (*) into :count trimmed
  from 
  ( select distinct * from class );
quit;

data want;
  set class;
  do _n_ = 1 to &count;
    output;
  end;
run;```

Regardless of what approach you choose, OUTER JOINS can get BIG QUICK, and thus cause lots of time consuming disk i/o.
...