BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
FRAFLUTE
Calcite | Level 5

Good Morning!

 

I have this situation:

Cust. CodeCust NameContract stateContract NumberPlateDriver CodeDriver Name
123456CUST1Active801223333AA123BB345678PIPPO
123456CUST1Active801223399AA126FF455554DONALD
123456CUST1Definition801370974BB123CC345678PIPPO
124345CUST 2Active801223433AA345BC565555PLUTO
124345CUST 2Active801223533AA678CC987755TOPOLINO
124345CUST 2Active801371117AA222RR121222MINNIE
124345CUST 2Active801371074BB567EE565555PLUTO
124345CUST 2Active801371174BB778CC987755TOPOLINO

 

I want to run through the db and when he find a row with same Cust. Id, the same User code, and contract number > to the first one i want to traspose the data. For example i want after the code this situation below:

 

Cust. CodeCust NameContract stateContract NumberPlateUser IdUser NameCust. Code RelCust Name RelContract state RelContract Num RelPlate relUser ID RelUser Name Rel
123456CUST1Active801223333AA123BB345678PIPPO123456CUST1Definition801370974BB123CC345678PIPPO
123456CUST1Active801223399AA126FF455554DONALD       
124345CUST 2Active801223433AA345BC565555PLUTO124345CUST 2Active801371074BB567EE565555PLUTO
124345CUST 2Active801223533AA678CC987755TOPOLINO124345CUST 2Active801371174BB778CC987755TOPOLINO
124345CUST 2Active801371117AA222RR121222MINNIE       

 

How can i create this second table?

 

Thanks for the support!

1 ACCEPTED SOLUTION

Accepted Solutions
PeterClemmensen
Tourmaline | Level 20

Quick fix:

 

data want(drop=_:);
   do until (last.DriverCode);
      set temp;
      by CustCode CustName DriverCode;

      if DriverCode=0 then do;
         output;return;
      end;

      if first.DriverCode then do;
         _CustCode=CustCode;
         _CustName=CustName;
         _Contractstate=Contractstate;
         _ContractNumber=ContractNumber;
         _Plate=Plate;
         _DriverCode=DriverCode;
         _DriverName=DriverName;
      end;
      if last.DriverCode then do;
         CustCodeRel=CustCode;
         CustNameRel=CustName;
         ContractStateRel=Contractstate;
         ContractNumRel=ContractNumber;
         PlateRel=Plate;
         DriverCodeRel=DriverCode;
         DriverNameRel=DriverName;
         
         CustCode=_CustCode;
         CustName=_CustName;
         Contractstate=_Contractstate;
         ContractNumber=_ContractNumber;
         Plate=_Plate;
         DriverCode=_DriverCode;
         DriverName=_DriverName;
         if (first.DriverCode=last.DriverCode) then call missing(CustCodeRel,CustNameRel,ContractStateRel,ContractNumRel,PlateRel,DriverCodeRel,DriverNameRel);
         output;
      end;
   end;
run;

View solution in original post

11 REPLIES 11
PeterClemmensen
Tourmaline | Level 20

Quick question: Why do you want to do this? Seems to be part of a bigger problem?

 

Also, are you sure that only two obs matches each other? What if there were three?

FRAFLUTE
Calcite | Level 5

I need to do this because the row with the same user id and same customer id are row related and i need to traspone this field for make after some calculation.

PeterClemmensen
Tourmaline | Level 20

Quick n Dirty, but gets the job done

 

data have;
input CustCode CustName $ Contractstate :$20. ContractNumber Plate $ DriverCode DriverName $;
datalines;
123456 CUST1 Active 801223333 AA123BB 345678 PIPPO
123456 CUST1 Active 801223399 AA126FF 455554 DONALD
123456 CUST1 Definition 801370974 BB123CC 345678 PIPPO
124345 CUST2 Active 801223433 AA345BC 565555 PLUTO
124345 CUST2 Active 801223533 AA678CC 987755 TOPOLINO
124345 CUST2 Active 801371117 AA222RR 121222 MINNIE
124345 CUST2 Active 801371074 BB567EE 565555 PLUTO
124345 CUST2 Active 801371174 BB778CC 987755 TOPOLINO
;

proc sort data=have out=temp;
   by CustCode CustName DriverCode;
run;

data want(drop=_:);
   do until (last.DriverCode);
      set temp;
      by CustCode CustName DriverCode;
      if first.DriverCode then do;
         _CustCode=CustCode;
         _CustName=CustName;
         _Contractstate=Contractstate;
         _ContractNumber=ContractNumber;
         _Plate=Plate;
         _DriverCode=DriverCode;
         _DriverName=DriverName;
      end;
      if last.DriverCode then do;
         CustCodeRel=CustCode;
         CustNameRel=CustName;
         ContractStateRel=Contractstate;
         ContractNumRel=ContractNumber;
         PlateRel=Plate;
         DriverCodeRel=DriverCode;
         DriverNameRel=DriverName;
         
         CustCode=_CustCode;
         CustName=_CustName;
         Contractstate=_Contractstate;
         ContractNumber=_ContractNumber;
         Plate=_Plate;
         DriverCode=_DriverCode;
         DriverName=_DriverName;
         if first.DriverCode=last.DriverCode then call missing(CustCodeRel,CustNameRel,ContractStateRel,ContractNumRel,PlateRel,DriverCodeRel,DriverNameRel);
         output;
      end;
   end;
run;

Result:

 

CustCode CustName Contractstate ContractNumber Plate   DriverCode DriverName CustCodeRel CustNameRel ContractStateRel ContractNumRel PlateRel DriverCodeRel DriverNameRel 
123456   CUST1    Active        801223333      AA123BB 345678     PIPPO      123456      CUST1       Definition       801370974      BB123CC  345678        PIPPO 
123456   CUST1    Active        801223399      AA126FF 455554     DONALD     .                                        .                       .             
124345   CUST2    Active        801371117      AA222RR 121222     MINNIE     .                                        .                       .             
124345   CUST2    Active        801223433      AA345BC 565555     PLUTO      124345      CUST2       Active           801371074      BB567EE  565555        PLUTO 
124345   CUST2    Active        801223533      AA678CC 987755     TOPOLINO   124345      CUST2       Active           801371174      BB778CC  987755        TOPOLINO 
FRAFLUTE
Calcite | Level 5

Great!!! It works!!!

 

But now i've just one problem. There are some Driver Code that have value like 0 where i dont want to traspose anythink. In this case it's possible to insert an "if DriverCode=0"  jump to the next Driver Code?

 

Thank u for the very usefull support!!!

PeterClemmensen
Tourmaline | Level 20

@FRAFLUTE are you able to provide an example of that? Preferably with the 'have' data set that I posted above? 

FRAFLUTE
Calcite | Level 5

Yes!

data have;
input CustCode CustName $ Contractstate :$20. ContractNumber Plate $ DriverCode DriverName $;
datalines;
123456 CUST1 Active 801223333 AA123BB 345678 PIPPO
123456 CUST1 Active 801223399 AA126FF 455554 DONALD
123456 CUST1 Definition 801370974 BB123CC 345678 PIPPO
124345 CUST2 Active 801223433 AA345BC 565555 PLUTO
124345 CUST2 Active 801223533 AA678CC 987755 TOPOLINO
124345 CUST2 Active 801371117 AA222RR 121222 MINNIE
124345 CUST2 Active 801371074 BB567EE 565555 PLUTO
124345 CUST2 Active 801371174 BB778CC 987755 TOPOLINO
124345 CUST2 Active 801271444 AW888RR 0      . 
124345 CUST2 Active 801277744 BW258JR 0      .
;


proc sort data=have out=temp;
   by CustCode CustName DriverCode;
run;

data want(drop=_:);
   do until (last.DriverCode);
      set temp;
      by CustCode CustName DriverCode;
      if first.DriverCode then do;
         _CustCode=CustCode;
         _CustName=CustName;
         _Contractstate=Contractstate;
         _ContractNumber=ContractNumber;
         _Plate=Plate;
         _DriverCode=DriverCode;
         _DriverName=DriverName;
      end;
      if last.DriverCode then do;
         CustCodeRel=CustCode;
         CustNameRel=CustName;
         ContractStateRel=Contractstate;
         ContractNumRel=ContractNumber;
         PlateRel=Plate;
         DriverCodeRel=DriverCode;
         DriverNameRel=DriverName;
         
         CustCode=_CustCode;
         CustName=_CustName;
         Contractstate=_Contractstate;
         ContractNumber=_ContractNumber;
         Plate=_Plate;
         DriverCode=_DriverCode;
         DriverName=_DriverName;
         if first.DriverCode=last.DriverCode then call missing(CustCodeRel,CustNameRel,ContractStateRel,ContractNumRel,PlateRel,DriverCodeRel,DriverNameRel);
         output;
      end;
   end;
run;

This is the cod whit this situation... in the last 2 row you see that the DriverCode value is 0. In this case, when DriverCode is 0 i want that the code dont make any traspose and the coluon with rel data are blank.

PeterClemmensen
Tourmaline | Level 20

Quick fix:

 

data want(drop=_:);
   do until (last.DriverCode);
      set temp;
      by CustCode CustName DriverCode;

      if DriverCode=0 then do;
         output;return;
      end;

      if first.DriverCode then do;
         _CustCode=CustCode;
         _CustName=CustName;
         _Contractstate=Contractstate;
         _ContractNumber=ContractNumber;
         _Plate=Plate;
         _DriverCode=DriverCode;
         _DriverName=DriverName;
      end;
      if last.DriverCode then do;
         CustCodeRel=CustCode;
         CustNameRel=CustName;
         ContractStateRel=Contractstate;
         ContractNumRel=ContractNumber;
         PlateRel=Plate;
         DriverCodeRel=DriverCode;
         DriverNameRel=DriverName;
         
         CustCode=_CustCode;
         CustName=_CustName;
         Contractstate=_Contractstate;
         ContractNumber=_ContractNumber;
         Plate=_Plate;
         DriverCode=_DriverCode;
         DriverName=_DriverName;
         if (first.DriverCode=last.DriverCode) then call missing(CustCodeRel,CustNameRel,ContractStateRel,ContractNumRel,PlateRel,DriverCodeRel,DriverNameRel);
         output;
      end;
   end;
run;
FRAFLUTE
Calcite | Level 5
Great Job!!!! Thank u so much!!! 🙂
mkeintz
PROC Star

 

Are the data already grouped by cust. code/cust name/contract number, so that matching records are already contiguous?

 

 

 

 

--------------------------
The hash OUTPUT method will overwrite a SAS data set, but not append. That can be costly. Consider voting for Add a HASH object method which would append a hash object to an existing SAS data set

Would enabling PROC SORT to simultaneously output multiple datasets be useful? Then vote for
Allow PROC SORT to output multiple datasets

--------------------------
FRAFLUTE
Calcite | Level 5

They are not already grouped but i can group by cust code and user code. The contract code change and the second one is major than the previously. 

 

Thank's!

Ready to join fellow brilliant minds for the SAS Hackathon?

Build your skills. Make connections. Enjoy creative freedom. Maybe change the world. Registration is now open through August 30th. Visit the SAS Hackathon homepage.

Register today!
Mastering the WHERE Clause in PROC SQL

SAS' Charu Shankar shares her PROC SQL expertise by showing you how to master the WHERE clause using real winter weather data.

Find more tutorials on the SAS Users YouTube channel.

Discussion stats
  • 11 replies
  • 858 views
  • 0 likes
  • 3 in conversation