Как вы в SAS возвращаете список всех столбцов во всех таблицах в библиотеке, которые содержат целевое значение? - PullRequest
4 голосов
/ 30 мая 2019

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

Если я ищу 'SomeString' или someNumericValue в Library = SomeLibrary, я хочу, чтобы код выводил таблицу со списком tableName ColumnName, содержащую искомое значение.

Proc SQL: Выбрать * столбцыC из всех таблиц в библиотеке L, которые содержат значение или строку = 'SomeValue'

Ответы [ 3 ]

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

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

Модифицированный код

libname temp "Y:\temp\t";
data temp.aa;
a=0;
b=0;
test="String";
run;

data temp.bb;
a=1;
c=0;
d=1;
run;

data temp.cc;
a=0;
b=1;
e=1;
run;

proc sql;
create table info
as
select memname as table, name as column from dictionary.columns
where upcase(type)="NUM" /*upcase(type)="CHAR"*/
and libname='TEMP'
order by memname;
quit;

options merror mprint nosymbolgen nomlogic;
data info1;
length coltab $1000.;
 set info;
 newtab=catx("_","TEMPT",_n_);
 condition=column||"=1"; /*Set Desired value here*/
 tab=("'"||table||"' as tab_name");
 var=("'"||column||"' as var_name");
 coltab="create table "||newtab||" as Select "||column||","||tab||","||var||" from temp."||table|| "where "||condition||";";
run;

proc sql noprint;
select count(*) into: nobs from info1;
quit;

%macro process;
%do i=1 %to &nobs;
    Data _null_;
        Set info1(firstobs=&i obs=&i);
        call symput('query',coltab);
    run;
    proc sql noprint;
        &Query;
    quit;
%end;
%mend;

%process;

proc sql noprint;
select distinct memname into :gt separated by " " from dictionary.columns where memname like '%TEMPT%';
quit;

%macro split(var);
%let var_c=%sysfunc(countw(&var));
%do i=1 %to &var_c;
    %let var_t=%sysfunc(scan(&var,&i));

    proc sql noprint;
    select count(*) into :cnt from &var_t;
    quit;

    %if &cnt=0 %then
    %do;
        proc datasets lib=work nolist;   
        delete &var_t; 
        quit;
        run;
    %end;
%end;
%mend split;

%split(&gt);

proc sql noprint;
select distinct memname into :gt0 separated by " " from dictionary.columns where memname like '%TEMPT%';
quit;

data all;
 set &gt0;
 keep tab_name var_name;
run;

proc sort data=all; by tab_name; run;

data final;
length vars $100.;
 set all;
  by tab_name;
  retain vars '';
  if first.tab_name then vars=var_name;
  else vars=catx(",",vars,var_name);
  if last.tab_name;
  drop var_name;
run;

proc print data=final; run;
0 голосов
/ 05 июня 2019

Proc contents может создать таблицу имен наборов данных для сканирования. Макрос сканирования, скажем, %scanner, может быть записан и вызван для каждого набора данных с помощью call execute. Результаты сканирования, имя набора данных и столбец, содержащий цель, могут быть добавлены в таблицу «все результаты».

Пример:

Для простоты предполагается, что ни в одном наборе данных не содержится более 10K переменных типа целевого значения - код выдает предупреждение, если сканирование будет обрезано.

Примечание: Пример строковой цели будет ..., target="Jane", ...

%macro scanner (libname=, memname=, target=20500, flagMax = 10000);
  %local type;

  %if %qsysfunc(dequote(&target)) = %superq(target) %then 
    %let type = _numeric_;
  %else 
    %let type = _character_;

  data hits(keep=__libname __memname __varname);
    array __flag (&flagMax) _temporary_;

    set &libname..&memname;

    array __candidates &type;

    if dim(__candidates) = 0 then stop;

    do __index = 1 to min (dim(__candidates), &flagMax);
      if not __flag(__index) then 
        if __candidates(__index) = &target then do;
          length __libname $8;
          length __memname __varname $32;
          __libname = "&libname";
          __memname = "&memname";
          __varname = vname(__candidates(__index));
          __flag(__index) = 1;

          OUTPUT;
        end;          
    end;

    if _n_ = 1 then
      if dim(__candidates) > &flagMax then put "WARNING: &memname has more than &flagMax variables - scanning will be clipped. Increase flagMax=.";
  run;

  proc append base=hasTarget data=hits(rename=(__libname=libname __memname=memname __varname=varname));
  run;
%mend;

proc sql;
  create table hasTarget (libname char(8), memname char(32), varname char(32));
quit;

%let libname = SASHELP;

ods noresults;
ods output members=datasets;
proc datasets library=&libname memtype=data;
run;
quit;
ods results;

data _null_;
  set datasets(keep=name memtype);
  where memtype = 'DATA';

  call execute (cats('%nrstr(%scanner(libname=' || "&LIBNAME., " || "memname=", name, '))'));
run;
0 голосов
/ 31 мая 2019

Отличный вызов!Я могу вам кое-что объяснить - макрос mp_searchdata библиотеки Macrocore Boemska запросит все таблицы в библиотеке (исходной базе данных) на наличие строкового или числового значения.Он возвращает все столбцы, но будет фильтровать только совпадающие записи.

Для выполнения:

/* import library */
filename mc url "https://raw.githubusercontent.com/Boemska/macrocore/master/macrocore.sas";
%inc mc;

/* run macro */
%mp_searchdata(lib=yourlib, string=SomeString)
...