Цикл для набора данных в SAS EG proc SQL - PullRequest
0 голосов
/ 16 мая 2019

Я новичок в SAS EG и хочу знать, как добавлять числа с помощью циклов на основе значений трех столбцов в SAS EG. Например.

Столбец0 Столбец1 Уровень столбца2 (желаемый результат) 1А АА 0 1A 123AA AA 1 1А 234АА 123АА 2 2B BB 0 2B 123BB BB 1 2B 234BB BB 1 2B 345BB 123BB 2 2B 456BB 345BB 3

Хотелось бы узнать, можно ли как-нибудь сделать vlookup для той же таблицы и добавить новый столбец для сохранения данных результатов в той же таблице?

1 Ответ

0 голосов
/ 16 мая 2019

SQL не знает о порядке строк, хранящихся на диске, и у ваших данных нет дополнительного столбца для значений, которые могут указывать на SORTED BY.

Шаг DATA предлагает более простой подход, когда последовательность строк «прочитана». Хеш-объект с ключом column1 может поддерживать значение уровня из предыдущих строк, а column2 может использоваться как ключевое значение для поиска.

Например:

data have;
infile datalines missover;
input
Column0 $ Column1 $ Column2 $; datalines;
1A        AA             
1A        123AA     AA   
1A        234AA     123AA
2B        BB             
2B        123BB     BB   
2B        234BB     BB   
2B        345BB     123BB
2B        456BB     345BB
run;

data want;

  set have;
  by column0;

  if _n_ = 1  then do;
    declare hash lookup();
    lookup.defineKey('column1');
    lookup.defineData('level');
    lookup.defineDone();
  end;

  if first.column0 then
    lookup.Clear();

  if (lookup.find(key:column2) ne 0) then
    level = 0;
  else
    level + 1;

  lookup.add();
run;

Примечание. Приведенный выше подход может потребовать корректировки для работы в VIYA.

Чтобы сделать то же самое в SQL, требуется несколько шагов. Один шаг на каждый уровень вычисляется (или обнаруживается) для соответствующих детей.

proc sql;
  create table level0 as
  select child.*, 0 as level from have as child
  where child.column2 is null;

  %put &=SQLOBS;

  create table level1 as
  select child.*, 1 as level from level0 as parent join have as child
  on parent.column0 = child.column0 and child.column2 = parent.column1;

  %put &=SQLOBS;

  create table level2 as
  select child.*, 2 as level from level1 as parent join have as child
  on parent.column0 = child.column0 and child.column2 = parent.column1;

  %put &=SQLOBS;

  create table level3 as
  select child.*, 3 as level from level2 as parent join have as child
  on parent.column0 = child.column0 and child.column2 = parent.column1;

  %put &=SQLOBS;

  create table level4 as
  select child.*, 4 as level from level3 as parent join have as child
  on parent.column0 = child.column0 and child.column2 = parent.column1;

  %put &=SQLOBS; * 0 obs, so no more children needing parentage found;

  create table want as
  select * from level0 union 
  select * from level1 union
  select * from level2 union
  select * from level3 
  order by column0, level
  ;

Общий подход должен был бы повторяться до тех пор, пока SQLOBS не станет 0

  create table level&LOOPINDEX as
  select child.*, &LOOPINDEX as level 
  from level&LOOPINDEX_MINUS_1 as parent 
  join have as child
  on parent.column0 = child.column0 and child.column2 = parent.column1;
...