J'ai besoin de créer une table qui a environ 20k lignes, 10k colonnes. La table sera créée en fusionnant une douzaine de tables source dites A, B, C, .., F, et les colonnes doivent être ordonnées en conséquence (colonnes dans A d'abord, puis colonnes dans B, etc.). Le tableau A établit le dénominateur et contient toutes les observations nécessaires dans le tableau final. Toutes les tables ont la même clé unique pour la jointure / fusion.

Chaque table source est indépendante l'une de l'autre. Et le nombre de colonnes / quelles colonnes de la table source à fusionner ne peuvent pas être connus tant que la table source n'est pas prête. Parfois, une table source doit à nouveau être mise à jour après avoir déjà été fusionnée.

J'ai fait comme A jointure gauche B, jointure gauche C, jointure gauche D ...., et j'ai la sortie de chaque fusion enregistrée de manière incrémentielle.

Dans une situation où C doit être mis à jour vers C * et fusionné à nouveau. Y a-t-il un moyen de le faire efficacement, au lieu de faire quelque chose comme fusionner C *, fusionner D, ... encore une fois pour les tables après C *.

Ou parfois j'ai A, B, D ... F prêt. Et je les ai fusionnés selon l'ordre. Alors C est prêt. Je dois fusionner C en A, B et répéter la fusion pour d'autres tables une fois de plus. Un moyen de repenser la création de la sortie finale, pour éviter la redondance ??

En outre, l'index sur la clé doit-il être créé dans toutes les tables source dans ce domaine?

1
user159193 20 nov. 2018 à 23:57

3 réponses

Meilleure réponse

Si les identifiants sont uniques (c'est-à-dire que vous ne faites PAS de correspondance 1 à N ou N à M), fusionnez simplement toutes les tables en même temps.

data want ;
  merge a b c d e f ;
  by id;
run;

Vous pouvez mettre la liste des tables dans une variable macro.

%let table_list=a b c2 d e f;
data want ;
  merge &table_list;
  by id;
run;

Vous pouvez avoir la liste dans une table de métadonnées et générer le code à partir de la table de métadonnées.

proc sql noprint;
  select memname
    into :table_list separated by ' '
    from my_metadata
    order by order_num
  ;
quit;

En termes de mise à jour d'une seule des tables, voici une méthode qui devrait définir les noms de variables dans le bon ordre, mais sans avoir à relire toutes les données de toutes les tables.

Faites une liste des colonnes que vous souhaitez supprimer de la table "maître" actuelle qui provient de OLD_C dans la macro variable appelons DROPLIST. Pour vous assurer que les colonnes sont dans l'ordre, vous avez toujours besoin de la liste des tables, mais nous n'avons pas besoin de les relire toutes, nous avons juste besoin de pouvoir les ouvrir afin que SAS puisse trouver les noms des variables dans l'ordre . Notez que cette liste doit faire référence à la nouvelle version de C afin qu'elle voie les variables de cette version de C.

%let table_list=a b new_c d e f ;
%let droplist=c1 c2 c3 c4;
data new ;
  * Force new list of variables using NEW list of tables in order ;
  if 0 then set &table_list ;
  merge old(drop=&droplist) new_c ;
  by id;
run;
0
Tom 20 nov. 2018 à 21:40

@Tom answer for merge est le meilleur moyen de combiner les tables source au départ.

Le problème d'une situation initiale avec une table C ayant des colonnes, par exemple z1-z999, puis une C* suivante avec des colonnes dites z1-z250 et zed500-zed1729. Où les colonnes C d'origine qui ne sont pas dans C* (celles z251-z999) doivent-elles se trouver dans l'ordre des colonnes du tableau combiné?

Le cas d'un historique maintenu, fusionné avec de nouvelles données de structure similaire mais variable, peut être quelque peu géré si les nouvelles données englobent toujours un domaine souhaité de l'historique. L'option d'ensemble de données OBS=0 peut être utilisée avec des ensembles de données dans un merge afin de forcer la construction implicite du vecteur de données de programme (PDV) à avoir l'ordre des colonnes souhaité.

Par exemple

data history;
  merge
    a(obs=0)
    b(obs=0)
    c(obs=0)
    d(obs=0)
    e(obs=0)
    history a b c d e;
  ;
  by key;
run;

Les variables du PDV seront classées de la même manière que l'ordre d'apparition dans les ensembles de données a-e. Toutes les variables de history et non de a-e apparaîtront à l'extrême droite du PDV dans l'ordre indiqué dans le history en cours de mise à jour.

Une fois que vous avez compris comment la construction PDV peut être manipulée, vous pouvez développer des abstractions ou des règles de construction et appliquer la génération de code source souhaitée via la programmation de macros.

0
Richard 20 nov. 2018 à 21:43

C'est ce que je fais, lorsque je tire des données de la base de données SQL. J'extrais des données de différentes tables et crée des ensembles de données sas séparés principalement dans un ordre séquentiel, de sorte qu'il soit facile de les fusionner séparément via des macros. Ensuite, je les fusionne sur la base de clés communes.

%macro merging(otds, dsnum, keyvar);
%do i=1 %to &dsnum;
data out&i;
set in&i;
if ^missing(&keyvar);
run;
%end;
%do i=1 %to &dsnum;
proc sort data=out&i nodupkey;
by &keyvar;
run;
%end;
data &otds;
  merge
  %do i = 1 %to &dsnum;
    out&i
  %end; 
  ;
  by &keyvar;
  if &keyvar ne .;
run;
%mend;

%merge(outds,10,Key_Or_Id);

Donc, dans le code ci-dessus, j'ai 10 tables dans 1 sur 10 et celles-ci sont fusionnées avec des clés communes. Si l'une de ces tables est mise à jour plus tard, nous pouvons à nouveau fusionner en utilisant la même approche ... j'espère que cela vous aidera!

0
Rhythm 20 nov. 2018 à 21:31