Как выбрать несоответствие столбцов в SCD-Type2 через SAS - PullRequest
0 голосов
/ 27 сентября 2018

У нас есть таблицы SCD типа 2, почти 200 таблиц, по 250 столбцов в каждой таблице.

для EX: детали СТУДЕНТА

STUDENT_ID VALID_FROM_DT  VALID_TO_DT        NAME    CITY   CONTACT_NO  BRANCH  
   1        04-April-2018   10-April-2018    XYZ     Chennai  12345     CSE
   1       10-April-2018   31-DEC-2055       XYZ     MUMBAI   87777     CSE

в поисках какого-то общего решения, для которого требуется только точноенесоответствие столбцов для этого случая выходные данные должны быть

OUTPUT:

STUDENT_ID VALID_FROM_DT  VALID_TO_DT         CITY   CONTACT_NO    
   1        04-April-2018  10-April-2018      Chennai  12345    
   1       10-April-2018   31-DEC-2055        MUMBAI   87777     

Может ли это решение возможно, если это так, может быть, некоторые родовые, которые могут использовать это для всех моих 200 таблиц.

Ответы [ 2 ]

0 голосов
/ 28 сентября 2018

Большое количество таблиц измерений, каждая из которых имеет большое количество столбцов атрибутов, - это большая вещь для изучения.Для общего решения вам потребуется использовать информацию метаданных для получения списка наборов данных в библиотеке, проверить эти наборы данных на наличие признаков «scd2-idness» (например, столбец идентификатора, названный аналогично имени набора данных),Для каждой таблицы scd2 вы снова посещаете метаданные, чтобы получить столбцы не-scd (любой столбец, который не является идентификатором записи, идентификатором измерения или допустимым диапазоном дат).Затем будет записан процесс, проходящий через набор данных и идентифицирующий случаи, когда значение атрибута изменилось или не изменилось по сравнению с предыдущим допустимым диапазоном дат.

Рассмотрим некоторые сгенерированные данные scd-2 с произвольным именем измерения,имеющие произвольные имена атрибутов (то есть столбцов).Некоторые из столбцов в группе вынуждены быть «статичными» (это могут быть те столбцы, которые могут рассматриваться как опущенные в вашем вопросе)

%macro random_name(len=8);
  %local i result;
  %do i = 1 %to &len;
    %let result = &result.%sysfunc(byte(%sysfunc(ranuni(123))*26+65));
  %end;
  &result
%mend;

%macro make_data(lib=WORK, N=40);
  %local outcount i j p suffix out;
  %do outcount = 1 %to &N;
    %let out = dimtable_%random_name();
    %let idvar = &out._id;

    %local top cCount nCount cName nName namelen name;

    %let top  = %sysevalf ( 1000 * %sysfunc(ranuni(123)), FLOOR);
    %let nCount = %sysevalf ( 20 * %sysfunc(ranuni(123)), FLOOR);
    %let cCount = %sysevalf ( 20 * %sysfunc(ranuni(123)), FLOOR);

    %do i = 1 %to &nCount;
      %let namelen = %sysevalf(16 * %sysfunc(ranuni(123)), CEIL);
      %let name = ;
      %do j = 1 %to &namelen;
        %let name = &name.%sysfunc(byte(%sysfunc(ranuni(123))*26+65));
      %end;
      %local numvar&i;
      %let numvar&i = nattr&i._&name.;
    %end;

    %do i = 1 %to &cCount;
      %let namelen = %sysevalf(16 * %sysfunc(ranuni(123)), CEIL);
      %let name = ;
      %do j = 1 %to &namelen;
        %let name = &name.%sysfunc(byte(%sysfunc(ranuni(123))*26+65));
      %end;
      %local chrvar&i;
      %let chrvar&i = cattr&i._&name.;
    %end;

    data &out;
      do rowid = 1 to ⊤

        if rowid = 1 or ranuni(123) > 0.8 then do;
          &idvar + 1;

          valid_from_dt = 0;
          valid_to_dt   = '01-jan-1970'd + floor(60 * ranuni(123));

          format valid: yymmdd10.;

          attrib 
            %if &nCount %then %do; %do i = 1 %to &nCount; &&numvar&i %end; length=8 format=6. %end;
            %if &cCount %then %do; %do i = 1 %to &cCount; &&chrvar&i %end; length=$20 %end;
          ;

          %if &nCount %then %do; array num %do i = 1 %to &nCount;  &&numvar&i %end; ; %end;
          %if &cCount %then %do; array chr %do i = 1 %to &cCount;  &&chrvar&i %end; ; %end;

          array staticN[0:&nCount] _temporary_;
          array staticC[0:&cCount] _temporary_;

          do _n_ = 1 to hbound(staticN); staticN(_n_) = ranuni(123) < 0.40; end;
          do _n_ = 1 to hbound(staticC); staticC(_n_) = ranuni(123) < 0.40; end;

          do _n_ = 1 to dim(num);
            num(_n_) = CEIL (1000 * ranuni(123));
          end;
          do _n_ = 1 to dim(chr);
            chr(_n_) = repeat(byte(65+26*ranuni(123)), 15 * ranuni(123));
          end;
        end;

        valid_from_dt = valid_to_dt + 1;
        valid_to_dt   = valid_from_dt + ceil(60 * ranuni(123));

        do _n_ = 1 to dim(num);
          if not staticN(_n_) then num(_n_) = CEIL (1000 * ranuni(123));
        end;

        do _n_ = 1 to dim(chr);
          if not staticC(_n_) then chr(_n_) = repeat(byte(65+26*ranuni(123)), 15 * ranuni(123));
        end;

        output;
      end;
    run;
  %end;
%mend;

options mprint;

%let SCD2_LIB = WORK;

proc datasets nolist noprint lib=&SCD2_LIB mt=data kill;
run;
quit;

%make_data(lib=&SCD2_LIB, n=1)

Общий макрос экзаменационного scd-2 записывается на выходтаблица, которая содержит пропущенные значения (пробелы), когда значение атрибута не изменилось по сравнению с предыдущим допустимым диапазоном дат.Он не совсем «отбрасывается», но является хорошим визуальным средством для просмотра «пробелов», которые означают неизменную информацию.

Макрос вызывается другим процессом, который обнаруживает таблицы scd-2 и определяет числовые и символьные переменные, которые будутбыть рассмотрены как атрибуты, которые могут иметь изменения значения.Вывод сохраняется в соответствующем наборе данных с именем * _changed.

%macro scan_scd(data=, idvar=, nvars=, cvars=);

  %local i nCount cCount;

  %let nCount = %sysfunc(countw(&nvars));
  %let cCount = %sysfunc(countw(&cvars));

  %do i = 1 %to &nCount; %local nvar&i; %let nvar&i = %scan(&nvars,&i); %end;
  %do i = 1 %to &cCount; %local cvar&i; %let cvar&i = %scan(&cvars,&i); %end;

  data &data._changes;
    if 0 then set &data(keep=rowid &idvar valid_from_dt valid_to_dt);

    retain
        %do i = 1 %to &nCount; &&nvar&i &&nvar&i.._was %end;
        %do i = 1 %to &cCount; &&cvar&i &&cvar&i.._was %end;
    ;

    set 
      &data (obs=0 rename=(
        %do i = 1 %to &nCount; &&nvar&i = ___nprv&i %end; 
        %do i = 1 %to &cCount; &&cvar&i = ___cprv&i %end;
      ))
      &data (obs=0 rename=(
        %do i = 1 %to &nCount; &&nvar&i = &&nvar&i.._was %end; 
        %do i = 1 %to &cCount; &&cvar&i = &&cvar&i.._was %end;
      ))
      &data;

    by &idvar.;

    if first.&idvar. then do;
      %do i = 1 %to &nCount; ___nprv&i = &&nvar&i; %end;
      %do i = 1 %to &nCount; &&nvar&i.._was = .; %end;
      %do i = 1 %to &cCount; ___cprv&i = &&cvar&i; %end;
      %do i = 1 %to &cCount; &&cvar&i.._was = ''; %end;
    end;
    else do;
      %do i = 1 %to &nCount; &&nvar&i.._was = ifn (&&nvar&i = ___nprv&i, ., ___nprv&i); %end;
      %do i = 1 %to &cCount; &&cvar&i.._was = ifc (&&cvar&i = ___cprv&i,'', ___cprv&i); %end;

      %do i = 1 %to &nCount; ___nprv&i = &&nvar&i; %end;
      %do i = 1 %to &cCount; ___cprv&i = &&cvar&i; %end;
    end;
  run;
%mend;

scd-2, обнаружение и вызов сканирования

Имена всех таблиц в некоторой библиотеке-кандидате

proc sql;
  create table scd_datasets as select libname, memname from dictionary.tables
  where libname = "&SCD2_LIB"
  ;
quit;

имя файла mprint и опция mfile могут сохранять сгенерированный макрос во внешнем файле для более детального изучения и изучения;

filename mprint "c:\temp\macro-source.sas" ;
%let rc = %sysfunc(fdelete(%sysfunc(pathname(mprint))));

options nomprint;
options mprint mfile;

Обрабатывать каждый набор данных.Используйте функции набора данных для доступа к информации метаданных набора данных.

data _null_;
  set scd_datasets;
  scd_table = catx('.',libname,memname);
  scd_id_var = trim(memname) || '_ID';
  rowid_var = 'ROWID';
  from_dt_var = 'VALID_FROM_DT';
  to_dt_var = 'VALID_TO_DT';

  dsid = open (scd_table);
  if dsid then do;

    if varnum(dsid, scd_id_var) 
     & varnum(dsid, rowid_var)
     & varnum(dsid, from_dt_var)
     & varnum(dsid, to_dt_var)
    then do;

      length nvars $32000;
      length cvars $32000;

      nvars = '';
      cvars = '';

      do _n_ = 1 to attrn(dsid,'nvar');
        varname = upcase(varname(dsid,_n_));
        vartype = vartype(dsid,_n_);

        if varname ne upcase(scd_id_var)
         & varname ne rowid_var
         & varname ne from_dt_var
         & varname ne to_dt_var
        then do;
          if vartype = 'N' then nvars=catx(' ',nvars,varname);
          if vartype = 'C' then cvars=catx(' ',cvars,varname);
        end;
      end;

      %* Queue the invocation of the SCD-2 scanner macro for this particular data set;

      call execute (
%*        '%put NOTE: ' ||;
        '%nrstr(%scan_scd(' ||
          'data=' || trim(scd_table) ||
          ', idvar=' || scd_id_var ||
          ', nvars=' || trim(nvars) ||
          ', cvars=' || trim(cvars) ||
        '))'
      );
    end;

    dsid = close(dsid);
  end;
run;

options nomfile nomprint;
filename mprint;
0 голосов
/ 27 сентября 2018

Чандана К

Да, это возможно, и вам нужно создать универсальную макро-функцию для этого.Я вижу приведенный ниже пример с примером, который вы привели.

/* 1st function - table criteria */
%macro manytables(table, columns);
    data &table.(keep = &columns.); /* keep only the columns you want */
        set data_origin; /* Name of your source table */
    run;    
%mend;


/* Function wating 30 second for executuion*/
%macro waiting;
       data _null_;
              time_calc = sleep(1,30);
       run;
%mend;


%let BD = 0; /* initializes the count variable */

/* 2nd function - generate 200 tables about your criteria. */
%macro loop_200_tables;
    %do %while (&BD < 200);

         %waiting; /* to avoid network error and processing. */

         /* call your function */
         %manytables(STUDENT_details_&BD., STUDENT_ID VALID_FROM_DT VALID_TO_DT NAME CITY CONTACT_NO BRANCH);

         %let BD = %eval(&BD. + 1);
         %put STUDENT_details %eval(&BD. - 1) OK!;
         %PUT waiting new processing...;

    %end;

    %put finish;    
%MEND loop_200_tables;
%loop_200_tables;
...