<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Re: How to retrieve the last value in a &amp;quot;chain&amp;quot; of relationships without using reflexing j in SAS Procedures</title>
    <link>https://communities.sas.com/t5/SAS-Procedures/How-to-retrieve-the-last-value-in-a-quot-chain-quot-of/m-p/301142#M60580</link>
    <description>&lt;P&gt;With a file up to some thousands of clients you can use the attached tested program&lt;/P&gt;</description>
    <pubDate>Wed, 28 Sep 2016 02:09:04 GMT</pubDate>
    <dc:creator>Shmuel</dc:creator>
    <dc:date>2016-09-28T02:09:04Z</dc:date>
    <item>
      <title>How to retrieve the last value in a "chain" of relationships without using reflexing joins?</title>
      <link>https://communities.sas.com/t5/SAS-Procedures/How-to-retrieve-the-last-value-in-a-quot-chain-quot-of/m-p/301122#M60578</link>
      <description>&lt;P&gt;Hi all,&lt;/P&gt;
&lt;P&gt;I have a dataset with three columns with this kind of information:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;TABLE width="658"&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TD width="64"&gt;OBS&lt;/TD&gt;
&lt;TD width="111"&gt;DATE&lt;/TD&gt;
&lt;TD width="354"&gt;CLIENT_ID&lt;/TD&gt;
&lt;TD width="129"&gt;OLD_CLIENT_ID&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;1&lt;/TD&gt;
&lt;TD&gt;27-Sep-16&lt;/TD&gt;
&lt;TD&gt;10&lt;/TD&gt;
&lt;TD&gt;6&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;2&lt;/TD&gt;
&lt;TD&gt;27-Sep-16&lt;/TD&gt;
&lt;TD&gt;7&lt;/TD&gt;
&lt;TD&gt;5&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;3&lt;/TD&gt;
&lt;TD&gt;17-Jun-16&lt;/TD&gt;
&lt;TD&gt;6&lt;/TD&gt;
&lt;TD&gt;4&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;4&lt;/TD&gt;
&lt;TD&gt;10-Sep-16&lt;/TD&gt;
&lt;TD&gt;9&lt;/TD&gt;
&lt;TD&gt;8&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;5&lt;/TD&gt;
&lt;TD&gt;5-Mar-16&lt;/TD&gt;
&lt;TD&gt;4&lt;/TD&gt;
&lt;TD&gt;2&lt;/TD&gt;
&lt;/TR&gt;
&lt;/TBODY&gt;
&lt;/TABLE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Where "date" column is the date where some client&amp;nbsp;has made a change in his account id, and the other columns are the respective values at that moment.&lt;/P&gt;
&lt;P&gt;As you can see in the example dataset posted, many (and unknown) number of relationships could exist in the data history. For example, the client&amp;nbsp;"10" was before client&amp;nbsp;"6" (obs 1) but before was client&amp;nbsp;"4" and before of that was client&amp;nbsp;"2".&lt;/P&gt;
&lt;P&gt;Therefore, what I want is a final dataset with the client_id-old_client_id pair taking account of what was said before, which will be like this:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;TABLE width="594"&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TD width="111"&gt;OBS&lt;/TD&gt;
&lt;TD width="354"&gt;
&lt;P&gt;CLIENT_ID&lt;/P&gt;
&lt;/TD&gt;
&lt;TD width="129"&gt;OLD_CLIENT_ID&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;1&lt;/TD&gt;
&lt;TD&gt;10&lt;/TD&gt;
&lt;TD&gt;2&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;2&lt;/TD&gt;
&lt;TD&gt;7&lt;/TD&gt;
&lt;TD&gt;5&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;3&lt;/TD&gt;
&lt;TD&gt;9&lt;/TD&gt;
&lt;TD&gt;8&lt;/TD&gt;
&lt;/TR&gt;
&lt;/TBODY&gt;
&lt;/TABLE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Is there a way to accomplish this without using reflexive joins? As I said, number of relationships are unknown so making reflexive joins could be worst-performing.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Thanks in advance!&lt;/P&gt;</description>
      <pubDate>Tue, 27 Sep 2016 21:05:24 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Procedures/How-to-retrieve-the-last-value-in-a-quot-chain-quot-of/m-p/301122#M60578</guid>
      <dc:creator>lmignone</dc:creator>
      <dc:date>2016-09-27T21:05:24Z</dc:date>
    </item>
    <item>
      <title>Re: How to retrieve the last value in a "chain" of relationships without using reflexing j</title>
      <link>https://communities.sas.com/t5/SAS-Procedures/How-to-retrieve-the-last-value-in-a-quot-chain-quot-of/m-p/301139#M60579</link>
      <description>&lt;P&gt;I have the feeling that some in memory&amp;nbsp;methods are the right mean to solve your problem.&lt;/P&gt;&lt;P&gt;Before tryning to code the program, it is good to know how big is the dataset?&lt;/P&gt;&lt;P&gt;or more specifically:&lt;/P&gt;&lt;P&gt;- how many observations are in the dataset?&lt;/P&gt;&lt;P&gt;- how many clients are expected in the result dataset ?&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;one more question - is there any other variable that can be used to identify client uniquely ?&lt;/P&gt;&lt;P&gt;having such variable will simplify the code.&lt;/P&gt;</description>
      <pubDate>Tue, 27 Sep 2016 23:46:10 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Procedures/How-to-retrieve-the-last-value-in-a-quot-chain-quot-of/m-p/301139#M60579</guid>
      <dc:creator>Shmuel</dc:creator>
      <dc:date>2016-09-27T23:46:10Z</dc:date>
    </item>
    <item>
      <title>Re: How to retrieve the last value in a "chain" of relationships without using reflexing j</title>
      <link>https://communities.sas.com/t5/SAS-Procedures/How-to-retrieve-the-last-value-in-a-quot-chain-quot-of/m-p/301142#M60580</link>
      <description>&lt;P&gt;With a file up to some thousands of clients you can use the attached tested program&lt;/P&gt;</description>
      <pubDate>Wed, 28 Sep 2016 02:09:04 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Procedures/How-to-retrieve-the-last-value-in-a-quot-chain-quot-of/m-p/301142#M60580</guid>
      <dc:creator>Shmuel</dc:creator>
      <dc:date>2016-09-28T02:09:04Z</dc:date>
    </item>
    <item>
      <title>Re: How to retrieve the last value in a "chain" of relationships without using reflexing j</title>
      <link>https://communities.sas.com/t5/SAS-Procedures/How-to-retrieve-the-last-value-in-a-quot-chain-quot-of/m-p/301144#M60581</link>
      <description>&lt;P&gt;It can be done with indexed random access:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data have;
input OBS	DATE :anydtdte.	CLIENT_ID	OLD_CLIENT_ID;
format date yymmdd10.;
datalines;
1	27-Sep-16	10	6
2	27-Sep-16	7	5
3	17-Jun-16	6	4
4	10-Sep-16	9	8
5	5-Mar-16	4	2
;

proc sql;
create unique index client_id on have(client_id);
create table current_clients as
select client_id as last_id
from have 
where client_id not in (select old_client_id from have);
quit;

data want;
set current_clients;
client_id = last_id;
do i = 1 to 100 until(_error_); /* Prevent cycling */
    set have key=client_id / unique;
    if _error_ then do;
        first_id = client_id;
        output;
        end;
    else client_id = old_client_id;
    end;
_error_ = 0;
keep first_id last_id;
run;&lt;/CODE&gt;&lt;/PRE&gt;</description>
      <pubDate>Wed, 28 Sep 2016 02:33:00 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Procedures/How-to-retrieve-the-last-value-in-a-quot-chain-quot-of/m-p/301144#M60581</guid>
      <dc:creator>PGStats</dc:creator>
      <dc:date>2016-09-28T02:33:00Z</dc:date>
    </item>
    <item>
      <title>Re: How to retrieve the last value in a "chain" of relationships without using reflexing j</title>
      <link>https://communities.sas.com/t5/SAS-Procedures/How-to-retrieve-the-last-value-in-a-quot-chain-quot-of/m-p/301147#M60582</link>
      <description>&lt;P&gt;Below should work as long as you have enough memory for the hashes AND each parent has only one child (so it's a single chain and not a tree with branches).&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data chain;
   infile datalines truncover;
   input date date9. client_id old_client_id;
   format date date9.;
   datalines;
27-sep=16 10 6
27-sep-16 7 5
17-jun-16 6 4
10-sep-16 9 8
05-mar-16 4 2
05-mar-16 20 
; 
run;

data want(keep=date client_id old_client_id);
  set chain(keep=date client_id old_client_id);
  if _n_=1 then
    do;
      if 0 then set chain(keep=client_id old_client_id rename=(client_id=child old_client_id=parent));
      dcl hash root (dataset:'chain(keep=client_id old_client_id rename=(client_id=child old_client_id=parent))');
      _rc=root.defineKey('child');
      _rc=root.defineData('parent');
      _rc=root.defineDone();
      dcl hash leaf (dataset:'chain(keep=client_id old_client_id rename=(client_id=child old_client_id=parent) where=(parent ne .))');
      _rc=leaf.defineKey('parent');
      _rc=leaf.defineData('child');
      _rc=leaf.defineDone();

    end;
  
  parent=old_client_id;
  do while(root.find(key:parent)=0);
  end;

  child=client_id;
  do while(leaf.find(key:child)=0);
  end;
  
  if client_id=child then 
    do;
      old_client_id=parent;
      output;
    end;
run; 
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;In case your data volumes are high and performance becomes an issue then it would be possible to delete entries from the hashes once we found root and parent - but it would require additional coding and I've tried to keep things simple.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Wed, 28 Sep 2016 03:25:30 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Procedures/How-to-retrieve-the-last-value-in-a-quot-chain-quot-of/m-p/301147#M60582</guid>
      <dc:creator>Patrick</dc:creator>
      <dc:date>2016-09-28T03:25:30Z</dc:date>
    </item>
    <item>
      <title>Re: How to retrieve the last value in a "chain" of relationships without using reflexing j</title>
      <link>https://communities.sas.com/t5/SAS-Procedures/How-to-retrieve-the-last-value-in-a-quot-chain-quot-of/m-p/301211#M60586</link>
      <description>&lt;PRE&gt;
As Patrick did.
Assuming One client_id corresponding to One old_client_id.


data chain;
   infile datalines truncover;
   input date date9. client_id old_client_id;
   format date date9.;
   datalines;
27-sep=16 10 6
27-sep-16 7 5
17-jun-16 6 4
10-sep-16 9 8
05-mar-16 4 2
; 
run;
data start;
 if _n_=1 then do;
  if 0 then set chain;
  declare hash h(dataset:'chain');
  h.definekey('old_client_id');
  h.definedone();
 end;
set chain;
if h.check(key:client_id) ne 0;
keep client_id date;
run;
data want;
 if _n_=1 then do;
  if 0 then set chain;
  declare hash h(dataset:'chain');
  h.definekey('client_id');
  h.definedata('old_client_id');
  h.definedone(); 
 end;
set start;
rc=h.find();
do while(rc=0);
 rc=h.find(key:old_client_id);
end;
drop rc;
run;


&lt;/PRE&gt;</description>
      <pubDate>Wed, 28 Sep 2016 11:18:31 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Procedures/How-to-retrieve-the-last-value-in-a-quot-chain-quot-of/m-p/301211#M60586</guid>
      <dc:creator>Ksharp</dc:creator>
      <dc:date>2016-09-28T11:18:31Z</dc:date>
    </item>
    <item>
      <title>Re: How to retrieve the last value in a "chain" of relationships without using reflexing j</title>
      <link>https://communities.sas.com/t5/SAS-Procedures/How-to-retrieve-the-last-value-in-a-quot-chain-quot-of/m-p/301256#M60592</link>
      <description>&lt;P&gt;Hi Shmuel,&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Regarding your questions:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;- The dataset has ~ 4.000.000 obs.&lt;/P&gt;
&lt;P&gt;- The clients expected are ~95% of the obs of the dataset, as most of the relationships&amp;nbsp;has one change only.&lt;/P&gt;
&lt;P&gt;There is no other variable to identify the client uniquely.&lt;/P&gt;</description>
      <pubDate>Wed, 28 Sep 2016 13:29:44 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Procedures/How-to-retrieve-the-last-value-in-a-quot-chain-quot-of/m-p/301256#M60592</guid>
      <dc:creator>lmignone</dc:creator>
      <dc:date>2016-09-28T13:29:44Z</dc:date>
    </item>
    <item>
      <title>Re: How to retrieve the last value in a "chain" of relationships without using reflexing j</title>
      <link>https://communities.sas.com/t5/SAS-Procedures/How-to-retrieve-the-last-value-in-a-quot-chain-quot-of/m-p/301260#M60593</link>
      <description>&lt;P&gt;After testing the different solutions that were posted, I have to choose this one due to performance (45% faster processing than using reflexive sql joins).&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Thanks to all&amp;nbsp;&lt;img id="smileyhappy" class="emoticon emoticon-smileyhappy" src="https://communities.sas.com/i/smilies/16x16_smiley-happy.png" alt="Smiley Happy" title="Smiley Happy" /&gt;&lt;/P&gt;</description>
      <pubDate>Wed, 28 Sep 2016 13:34:23 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Procedures/How-to-retrieve-the-last-value-in-a-quot-chain-quot-of/m-p/301260#M60593</guid>
      <dc:creator>lmignone</dc:creator>
      <dc:date>2016-09-28T13:34:23Z</dc:date>
    </item>
  </channel>
</rss>

