Précédent   Forum des professionnels en informatique > Logiciels > Solutions d'entreprise > Business Intelligence > SAS > SAS Base
SAS Base Forum d'entraide sur SAS base : étape data, procédures non statistiques, procédures non graphiques, SQL
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 21/09/2011, 22h06   #1
Invité régulier
 
Femme Stéphanie
Business Analyst
Inscription : juillet 2011
Messages : 14
Détails du profil
Informations personnelles :
Nom : Femme Stéphanie

Informations professionnelles :
Activité : Business Analyst

Informations forums :
Inscription : juillet 2011
Messages : 14
Points : 5
Points : 5
Par défaut Ajout de colonne et Update

Salut à tous,

Je souhaite ajouter une colonne à une table déja existant (c'est un data set) et ensuite l'updater en fonction d'une autre de mes colonnes (avec une clause IF...then...).
Je suis habituée à SQL mais je n'arrive pas bien à retrouver ce que je veux dans mon code SAS, ce ne fonctionne pas...

Voici mon code actuel:
Code :
1
2
3
4
5
 
proc sql;
ALTER TABLE work.temp;
ADD PRODUCT_TYPE char format=20;
quit;
Donc la colonne PRODUCT_TYPE est celle que je veux ajouter, au format caractère.
Ensuite, je voudrais l'Updater avec une de mes colonnes deja existante, "PRODUCT" avec un IF 1 Then "POST"
IF 2 Then "PREP";

Merci d'avance de votre aide
StephMtl est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/09/2011, 06h30   #2
Expert Confirmé
 
Avatar de olivier.decourt
 
Homme Olivier Decourt
Formateur en informatique
Inscription : avril 2008
Messages : 1 467
Détails du profil
Informations personnelles :
Nom : Homme Olivier Decourt
Âge : 34
Localisation : France

Informations professionnelles :
Activité : Formateur en informatique
Secteur : Conseil

Informations forums :
Inscription : avril 2008
Messages : 1 467
Points : 2 828
Points : 2 828
Bonjour.
Quelque chose comme ça ?
Code :
1
2
3
4
5
6
7
8
9
10
11
12
DATA work.temp ;
  SET work.temp ;
  ATTRIB product_type
     LABEL="Descriptif de la variable"
     LENGTH=$ 20
  ;
  SELECT (product) ; /* équivaut au CASE WHEN en SQL */
     WHEN(1) product_type = "POST" ;
     WHEN(2) product_type = "PREP" ;
     OTHERWISE ;
  END ;
RUN ;
Pour l'association entre les valeurs de PRODUCT et celles de PRODUCT_TYPE, on pourrait aussi passer par un format.
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
PROC FORMAT ;
  VALUE produit
    1 = "POST"
    2 = "PREP"
    OTHER = "???"
  ;
RUN ;
DATA work.temp ;
  SET work.temp ;
  ATTRIB product_type
     LABEL="Descriptif de la variable"
     LENGTH=$ 20
  ;
  product_type = PUT(product, produit.) ;
RUN ;
Dernière solution, si tu n'as jamais besoin en même temps des 2 colonnes PRODUCT et PRODUCT_TYPE, c'est de juste créer le format comme ci-dessus (PROC FORMAT jusqu'à RUN) et ensuite de l'appliquer quand tu en as besoin (dans les procédures de calcul par exemple).
Code :
1
2
3
4
PROC FREQ DATA=work.temp ;
  TABLE product ;
  FORMAT product produit. ;
RUN ;
Bon courage.
Olivier
olivier.decourt est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/09/2011, 11h53   #3
Membre éclairé
 
Homme
statisticien
Inscription : mai 2011
Messages : 212
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France, Paris (Île de France)

Informations professionnelles :
Activité : statisticien
Secteur : Administration - Collectivité locale

Informations forums :
Inscription : mai 2011
Messages : 212
Points : 319
Points : 319
Bonjour,

si tu cherche une solution tout SQL, je pense que ce code devrait pouvoir faire ce que tu cherche à faire, a condition que tu dispose d'un identifiant pour réaliser la jointure entre tes tables et modulo ma compréhension de ton problème.

Code :
1
2
3
4
5
6
7
8
9
10
11
proc sql;
CREATE TABLE Resultat
AS SELECT tab1.*,coalescec(tab3.Product_Type,tab4.Product_Type,tab2.Product_Type) AS Product_Type
FROM PremiereTable AS tab1
LEFT JOIN
DeuxiemeTable AS tab2 ON tab1.id=tab2.id
LEFT JOIN
(SELECT id,'POST' AS Product_Type FROM Upgrade WHERE Product='1') AS tab3 ON tab1.id=tab3.id
LEFT JOIN
(SELECT id,'PREP' AS Product_Type FROM Upgrade WHERE Product='2') AS tab4 ON tab1.id=tab4.id;
quit;
Une autre syntaxe est également possible sans multiplier les tables...

Code :
1
2
3
4
5
6
7
8
9
10
11
12
proc sql;
CREATE TABLE Resultat
AS SELECT tab1.*,	case 	when tab3.Product='1' then 'POST'
							when tab3.Product='2' then 'PREP'
							else tab2.Product_Type
					end AS Product_Type
 
FROM PremiereTable AS tab1
LEFT JOIN
DeuxiemeTable AS tab2 ON tab1.id=tab2.id
LEFT JOIN
Upgrade AS tab3 ON tab1.id=tab3.id;quit;
jerome_pdv2 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/09/2011, 14h44   #4
Invité régulier
 
Femme Stéphanie
Business Analyst
Inscription : juillet 2011
Messages : 14
Détails du profil
Informations personnelles :
Nom : Femme Stéphanie

Informations professionnelles :
Activité : Business Analyst

Informations forums :
Inscription : juillet 2011
Messages : 14
Points : 5
Points : 5
[QUOTE=olivier.decourt;6253875]Bonjour.
Quelque chose comme ça ?
Code :
1
2
3
4
5
6
7
8
9
10
11
12
DATA work.temp ;
  SET work.temp ;
  ATTRIB product_type
     LABEL="Descriptif de la variable"
     LENGTH=$ 20
  ;
  SELECT (product) ; /* équivaut au CASE WHEN en SQL */
     WHEN(1) product_type = "POST" ;
     WHEN(2) product_type = "PREP" ;
     OTHERWISE ;
  END ;
RUN ;

Ce code marche très bien merci!
Maintenant je me pose une autre question (lol), dans la partie
Code :
1
2
3
4
5
6
7
 
SELECT (product) ; /* équivaut au CASE WHEN en SQL */
     WHEN(1) product_type = "POST" ;
     WHEN(2) product_type = "PREP" ;
     OTHERWISE ;
  END ;
RUN ;
est ce qu'il serait possible d'ajouter une autre variable après le select?
Admettons que mon update de colonne soit en fait dépendant de 2 variables différentes, on aurait donc la première product, et une seconde, disons "network", qui lorsqu'elle prend la valeur XYX, attribuerait l'intitulé XYZZ à la nouvelle colonne crée product_type.

Aussi, est il possible d'inclure une non condition dans cette clause? Du genre,
Code :
1
2
3
     WHEN(1) product_type = "POST" ;
     WHEN(<>2) product_type = "PREP" ;
(bien sûr, le <> n'a pas marché...)

Enfin, last but not least, est ce que je peux re-updater ma colonne plus tard? Parce que là j'update après avoir crée la colonne, mais puis je le faire en 2 étapes: créer, puis updater plus tard?

Merci beaucoup de votre aide!!

P.S: Je ne peux pas partir avec du pur sql car je n'ai pas vraiment de quoi faire une jointure correcte. En plus, ca me parait pas mal plus compliqué?
StephMtl est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/09/2011, 15h46   #5
Expert Confirmé
 
Avatar de olivier.decourt
 
Homme Olivier Decourt
Formateur en informatique
Inscription : avril 2008
Messages : 1 467
Détails du profil
Informations personnelles :
Nom : Homme Olivier Decourt
Âge : 34
Localisation : France

Informations professionnelles :
Activité : Formateur en informatique
Secteur : Conseil

Informations forums :
Inscription : avril 2008
Messages : 1 467
Points : 2 828
Points : 2 828
1) pour les conditions plus complexes, ça devient
Code :
1
2
3
4
5
6
SELECT ;
  WHEN (condition1) action1;
  WHEN (condition2) action2;
  etc.
  OTHERWISE actionN ;
END ;
Dans SAS, l'opérateur pour différent est plutôt NE (pour Not Equals) que <> qui ne marche pas partout.
2) oui tu peux définir ta variable un premier coup (il n'y a qu'à se limiter au bloc ATTRIB dans l'étape DATA) et l'alimenter / la rectifier ensuite. Dans SAS, ce n'est qu'une question de droits sur la table entière, pas sur une colonne en particulier : si tu peux écrire dans la table, tu peux en modifier toutes les variables.
Cela dit, pour créer un champ vide dans une table SAS de grosse taille, la proc SQL sera plus rapide que l'étape DATA (enfin je suppose, je n'ai rien testé).

Bon courage.
Olivier
olivier.decourt est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/09/2011, 17h36   #6
Invité régulier
 
Femme Stéphanie
Business Analyst
Inscription : juillet 2011
Messages : 14
Détails du profil
Informations personnelles :
Nom : Femme Stéphanie

Informations professionnelles :
Activité : Business Analyst

Informations forums :
Inscription : juillet 2011
Messages : 14
Points : 5
Points : 5
Super, merci beaucoup pour ton aide, j'apprécie vraiment

Allez, une dernière pour la route (lol).
Je ne trouve pas comment faire pour Updater ma colonne lorsque les cases sont vides, j'ai tenté le NULL mais ca n'a pas fonctionné!
StephMtl est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/09/2011, 18h16   #7
Expert Confirmé
 
Avatar de olivier.decourt
 
Homme Olivier Decourt
Formateur en informatique
Inscription : avril 2008
Messages : 1 467
Détails du profil
Informations personnelles :
Nom : Homme Olivier Decourt
Âge : 34
Localisation : France

Informations professionnelles :
Activité : Formateur en informatique
Secteur : Conseil

Informations forums :
Inscription : avril 2008
Messages : 1 467
Points : 2 828
Points : 2 828
La condition s'écrit
Code :
WHEN (MISSING(variable)) action ;
et vaut vrai en cas de NULL. Le souci de SAS c'est qu'il n'y a pas une seule valeur manquante comme NULL, il y en 29 (1 pour les textes et 28 pour les numériques) différentes ! Donc la fonction MISSING est la plus robuste.
olivier.decourt est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 29/09/2011, 15h53   #8
Invité de passage
 
Inscription : septembre 2011
Messages : 1
Détails du profil
Informations forums :
Inscription : septembre 2011
Messages : 1
Points : 1
Points : 1
Par défaut Une nouvelle idée peut-être ?

Bonjour,

J'espère avoir bien compris la question. Si c'est bien le cas je propose une syntaxe SQL qui se traite directement dans le SELECT.

Code :
1
2
3
4
5
6
7
8
9
10
proc sql;
     create table work.temp as
     select [liste de variables]
             , case
                       when PRODUCT = 1 then 'POST'
                       when PRODUCT = 2 then 'PREP'

               end as TYP_PRODUCT length 20
;
quit;
En une seule lecture de table (ce qui peut être avantageux si elle est de grande taille) la nouvelle variable est crée et garnie.
caravanserail est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 17h31.


 
 
 
 
Partenaires

Hébergement Web