<?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 Match on at least 2 keys in SAS Programming</title>
    <link>https://communities.sas.com/t5/SAS-Programming/Match-on-at-least-2-keys/m-p/93987#M257596</link>
    <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;I'm trying to create data set WANT from HAVE based on the condition that there must be a match on at least 2keys. I have two approaches that I have tried. Thanks to some SAS information at &lt;A href="http://www2.sas.com/proceedings/sugi27/p075-27.pdf"&gt;www2.sas.com/proceedings/sugi27/p075-27.pdf&lt;/A&gt; The SQL approach finds the match but becomes a time consuming and resource intensive approach when dealing with large data set. Approach 2 does work but definitely a lengthy process and I find it a bit difficult to follow and replicate.&lt;/P&gt;&lt;P&gt;Question: 1) Anyone has a different (3rd) approach to solving this problem? OR&lt;BR /&gt;2) Could anyone provide an enhancement to approach 2 by adding a new variable country (‘US’ for all participants) to data set work.HAVE and generate a data set work.WANT with the condition that there’s a match on at least 2 keys. Note: The client_ID value should not change (I think). Thanks&lt;/P&gt;&lt;P&gt;&lt;BR /&gt;&lt;STRONG&gt;HAVE&lt;/STRONG&gt;&lt;/P&gt;&lt;P&gt;&lt;BR /&gt;ADNUM SSN NAME DOB &lt;BR /&gt;101 856116534 ABCD 18760323 &lt;BR /&gt;187 856176354 ABCD 18760323 &lt;BR /&gt;233 856176354 ABCD 18670323 &lt;BR /&gt;456 850176534 ABCD 18760323 &lt;BR /&gt;490 856176534 ABEF 18670323 &lt;BR /&gt;535 856176534 ABGF 18760323 &lt;BR /&gt;601 856176534 ABEF 18760323 &lt;BR /&gt;632 856176534 ABEE 18760323 &lt;BR /&gt;879 856116534 ABEF 18760323 &lt;BR /&gt;911 856176534 ABGF 18760323 &lt;BR /&gt;919 123456789 JOHN 19000224 &lt;BR /&gt;200 000089712 DAVE 20000212&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;BR /&gt;&lt;STRONG&gt;WANT (ALLDATA8)&lt;/STRONG&gt;&lt;/P&gt;&lt;P&gt;ADNUM SSN NAME DOB &lt;STRONG&gt;Client_id&lt;/STRONG&gt;&lt;BR /&gt;101 856116534 ABCD 18760323 3&lt;BR /&gt;187 856176354 ABCD 18760323 3&lt;BR /&gt;233 856176354 ABCD 18670323 3&lt;BR /&gt;456 850176534 ABCD 18760323 3&lt;BR /&gt;490 856176534 ABEF 18670323 3&lt;BR /&gt;535 856176534 ABGF 18760323 3&lt;BR /&gt;601 856176534 ABEF 18760323 3&lt;BR /&gt;632 856176534 ABEE 18760323 3&lt;BR /&gt;879 856116534 ABEF 18760323 3&lt;BR /&gt;911 856176534 ABGF 18760323 3&lt;BR /&gt;919 123456789 JOHN 19000224 2&lt;BR /&gt;200 000089712 DAVE 20000212 1&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp; &lt;BR /&gt;/* SQL approach */&lt;BR /&gt;PROC SQL;&lt;BR /&gt;CREATE TABLE work.match AS&lt;BR /&gt;SELECT X.ADNUM AS ADNUM1,&lt;BR /&gt;Y.ADNUM AS ADNUM2&lt;BR /&gt;FROM work.have X, work.have Y&lt;BR /&gt;WHERE ( (X.SSN EQ Y.SSN)&lt;BR /&gt;+ (X.NAME EQ Y.NAME)&lt;BR /&gt;+ (X.DOB EQ Y.DOB) ) &amp;gt;= 2&lt;BR /&gt;AND (X.ADNUM &amp;lt; Y.ADNUM)&lt;BR /&gt;ORDER BY ADNUM1, ADNUM2;&lt;BR /&gt;QUIT;&lt;/P&gt;&lt;P&gt;&lt;BR /&gt;/* Approach 2*/&lt;BR /&gt;DATA ALLDATA1 /*(KEEP = ADNUM NSID SDID NDID)*/;&lt;BR /&gt;SET work.have;/* imported data or created data set*/&lt;BR /&gt;LENGTH NSID $ 13 SDID $ 17 NDID $ 12&lt;BR /&gt;DOBC $ 8;&lt;BR /&gt;DOBC = TRIM(LEFT(COMPRESS(PUT(DOB,&lt;BR /&gt;BEST12.),'-')));&lt;BR /&gt;NSID = TRIM(NAME)||TRIM(SSN);&lt;BR /&gt;NDID = TRIM(NAME)||DOBC;&lt;BR /&gt;SDID = TRIM(SSN)||DOBC;&lt;BR /&gt;RUN;&lt;BR /&gt;%MACRO GENKEY(INDATA_ = , /* INPUT DATA */&lt;BR /&gt;OUTDATA_ = , /* OUTPUT DATA */&lt;BR /&gt;KEYID_ = /* BY VAR. */);&lt;BR /&gt;%LOCAL INDATA_ OUTDATA_ KEYID_;&lt;BR /&gt;PROC SORT DATA = &amp;amp;INDATA_;&lt;BR /&gt;BY &amp;amp;KEYID_.ID;&lt;BR /&gt;RUN;&lt;BR /&gt;DATA &amp;amp;OUTDATA_(DROP = &amp;amp;KEYID_.ID);&lt;BR /&gt;SET &amp;amp;INDATA_;&lt;BR /&gt;BY &amp;amp;KEYID_.ID;&lt;BR /&gt;IF FIRST.&amp;amp;KEYID_.ID THEN &amp;amp;KEYID_.KEY+1;&lt;BR /&gt;RUN;&lt;BR /&gt;%MEND GENKEY;&lt;BR /&gt;%GENKEY(INDATA_ = ALLDATA1,&lt;BR /&gt;OUTDATA_ = ALLDATA2,&lt;BR /&gt;KEYID_ = NS)&lt;BR /&gt;%GENKEY(INDATA_ = ALLDATA2,&lt;BR /&gt;OUTDATA_ = ALLDATA3,&lt;BR /&gt;KEYID_ = ND)&lt;BR /&gt;%GENKEY(INDATA_ = ALLDATA3,&lt;BR /&gt;OUTDATA_ = ALLDATA4,&lt;BR /&gt;KEYID_ = SD)&lt;BR /&gt;%MACRO GENFMTS(INDATA_ = , /* INPUT DATA */&lt;BR /&gt;FMTS_ = , /* FORMATS NAME */&lt;BR /&gt;KEY1_ = , /* WITHIN */&lt;BR /&gt;KEY2_ = /* TRANSLATE */);&lt;BR /&gt;%LOCAL INDATA_ FMTS_ KEY1_ KEY2_;&lt;BR /&gt;PROC SORT DATA = &amp;amp;INDATA_;&lt;BR /&gt;BY &amp;amp;KEY1_.KEY &amp;amp;KEY2_.KEY;&lt;BR /&gt;RUN;&lt;BR /&gt;DATA &amp;amp;FMTS_.0(KEEP = FMTNAME START LABEL&lt;BR /&gt;KEY);&lt;BR /&gt;SET &amp;amp;INDATA_;&lt;BR /&gt;BY &amp;amp;KEY1_.KEY;&lt;BR /&gt;RETAIN FMTNAME "&amp;amp;FMTS_" &amp;amp;KEY2_.KEYF;&lt;BR /&gt;IF FIRST.&amp;amp;KEY1_.KEY&lt;BR /&gt;THEN &amp;amp;KEY2_.KEYF = &amp;amp;KEY2_.KEY;&lt;BR /&gt;IF &amp;amp;KEY2_.KEY NE &amp;amp;KEY2_.KEYF THEN&lt;BR /&gt;DO;&lt;BR /&gt;START = &amp;amp;KEY2_.KEY;&lt;BR /&gt;LABEL = &amp;amp;KEY2_.KEYF;&lt;BR /&gt;KEY + 1;&lt;BR /&gt;OUTPUT;&lt;BR /&gt;END;&lt;BR /&gt;RUN;&lt;BR /&gt;PROC SORT DATA = &amp;amp;FMTS_.0 NODUPKEY;&lt;BR /&gt;BY START LABEL;&lt;BR /&gt;RUN;&lt;BR /&gt;%MEND GENFMTS;&lt;BR /&gt;%GENFMTS(INDATA_ = ALLDATA4,&lt;BR /&gt;FMTS_ = TRANSND,&lt;BR /&gt;KEY1_ = SD,&lt;BR /&gt;KEY2_ = ND) /* Tested to this level */&lt;BR /&gt;%MACRO TRANS(INDATA_ = ,&lt;BR /&gt;OUTDATA_ = ,&lt;BR /&gt;INIFMTS_ = ,&lt;BR /&gt;FINFMTS_ = ,&lt;BR /&gt;TRANS_ = );&lt;BR /&gt;%LOCAL&lt;BR /&gt;INDATA_ /* INPUT DATA SET */&lt;BR /&gt;OUTDATA_ /* OUTPUT DATA SET */&lt;BR /&gt;INIFMTS_ /* INITIAL FORMATS */&lt;BR /&gt;FINFMTS_ /* FINAL FORMATS */&lt;BR /&gt;TRANS_ /* **KEY TO BE TRANSLATED */&lt;BR /&gt;NEWOBS /* OBS. IN INITIAL FORMATS */&lt;BR /&gt;OLDOBS /* OBS. IN FINAL FORMATS */&lt;BR /&gt;LKOBS /* NUM OF LINK CASES TO BE&lt;BR /&gt;UPDATED IN EACH ITERATION */&lt;BR /&gt;REOBS /* NUM OF REPEAT CASES TO BE&lt;BR /&gt;UPDATED IN EACH ITERATION */&lt;BR /&gt;ITERS /* NUM OF ITERATIONS */&lt;BR /&gt;UP /* SERIES NUMBER FOR THE&lt;BR /&gt;TEMPORARY UPDATE DATA SET */&lt;BR /&gt;LK /* SERIES NUMBER FOR THE&lt;BR /&gt;TEMPORARY LINK DATA SET */&lt;BR /&gt;RE /* SERIES NUMBER FOR THE&lt;BR /&gt;TEMPORARY REPEAT DATA SET */&lt;BR /&gt;;&lt;BR /&gt;%LET UP = 1;&lt;BR /&gt;%LET LK = 1;&lt;BR /&gt;%LET RE = 1;&lt;BR /&gt;%LET ITERS = 0;&lt;BR /&gt;DATA _NULL_;&lt;BR /&gt;CALL SYMPUT('OLDOBS',&lt;BR /&gt;TRIM(LEFT(PUT(OLDOBS,10.))));&lt;BR /&gt;SET &amp;amp;INIFMTS_ NOBS = OLDOBS;&lt;BR /&gt;STOP;&lt;BR /&gt;RUN;&lt;BR /&gt;%PUT %STR( );&lt;BR /&gt;%PUT NOTE: DATA SET &amp;amp;INIFMTS_ HAS &amp;amp;OLDOBS&lt;BR /&gt;OBSERVATION PAIRS.;&lt;BR /&gt;PROC SQL;&lt;BR /&gt;CREATE TABLE LINK&amp;amp;LK AS&lt;BR /&gt;SELECT Y.KEY AS KEY,&lt;BR /&gt;Y.START AS START,&lt;BR /&gt;X.LABEL AS LABEL&lt;BR /&gt;FROM &amp;amp;INIFMTS_ X, &amp;amp;INIFMTS_ Y&lt;BR /&gt;WHERE X.START EQ Y.LABEL&lt;BR /&gt;ORDER BY KEY, START, LABEL;&lt;BR /&gt;QUIT;&lt;BR /&gt;PROC SQL;&lt;BR /&gt;CREATE TABLE REPEAT&amp;amp;RE AS&lt;BR /&gt;SELECT Y.KEY AS KEY,&lt;BR /&gt;Y.LABEL AS START,&lt;BR /&gt;X.LABEL AS LABEL&lt;BR /&gt;FROM &amp;amp;INIFMTS_ X, &amp;amp;INIFMTS_ Y&lt;BR /&gt;WHERE (X.START EQ Y.START)&lt;BR /&gt;AND (Y.LABEL &amp;gt; X.LABEL)&lt;BR /&gt;ORDER BY KEY, START, LABEL;&lt;BR /&gt;QUIT;&lt;BR /&gt;DATA _NULL_;&lt;BR /&gt;CALL SYMPUT('LKOBS',&lt;BR /&gt;TRIM(LEFT(PUT(LINK,10.))));&lt;BR /&gt;SET LINK&amp;amp;LK NOBS = LINK;&lt;BR /&gt;STOP;&lt;BR /&gt;RUN;&lt;BR /&gt;%PUT %STR( );&lt;BR /&gt;%PUT NOTE: DATA SET LINK&amp;amp;LK HAS &amp;amp;LKOBS&lt;BR /&gt;OBSERVATION PAIRS.;&lt;BR /&gt;DATA _NULL_;&lt;BR /&gt;CALL SYMPUT('REOBS',&lt;BR /&gt;TRIM(LEFT(PUT(REPEAT,10.))));&lt;BR /&gt;SET REPEAT&amp;amp;RE NOBS = REPEAT;&lt;BR /&gt;STOP;&lt;BR /&gt;RUN;&lt;BR /&gt;%PUT %STR( );&lt;BR /&gt;%PUT NOTE: DATA SET REPEAT&amp;amp;RE HAS &amp;amp;REOBS&lt;BR /&gt;OBSERVATION PAIRS.;&lt;BR /&gt;%DO %WHILE ((&amp;amp;LKOBS NE 0)&lt;BR /&gt;OR (&amp;amp;REOBS NE 0));&lt;BR /&gt;PROC SORT DATA = &amp;amp;INIFMTS_;&lt;BR /&gt;BY KEY;&lt;BR /&gt;RUN;&lt;BR /&gt;DATA UPDT&amp;amp;UP;&lt;BR /&gt;UPDATE &amp;amp;INIFMTS_ LINK&amp;amp;LK;&lt;BR /&gt;BY KEY;&lt;BR /&gt;RUN;&lt;BR /&gt;DATA UPDT%EVAL(&amp;amp;UP+1);&lt;BR /&gt;UPDATE UPDT&amp;amp;UP REPEAT&amp;amp;RE;&lt;BR /&gt;BY KEY;&lt;BR /&gt;RUN;&lt;BR /&gt;PROC SORT DATA = UPDT%EVAL(&amp;amp;UP+1)&lt;BR /&gt;NODUPKEY;&lt;BR /&gt;BY START LABEL;&lt;BR /&gt;RUN;&lt;BR /&gt;PROC SQL;&lt;BR /&gt;CREATE TABLE LINK%EVAL(&amp;amp;LK+1) AS&lt;BR /&gt;SELECT Y.KEY AS KEY,&lt;BR /&gt;Y.START AS START,&lt;BR /&gt;X.LABEL AS LABEL&lt;BR /&gt;FROM UPDT%EVAL(&amp;amp;UP+1) X,&lt;BR /&gt;UPDT%EVAL(&amp;amp;UP+1) Y&lt;BR /&gt;WHERE X.START EQ Y.LABEL&lt;BR /&gt;ORDER BY KEY, START, LABEL;&lt;BR /&gt;QUIT;&lt;BR /&gt;PROC SQL;&lt;BR /&gt;CREATE TABLE REPEAT%EVAL(&amp;amp;RE+1) AS&lt;BR /&gt;SELECT Y.KEY AS KEY,&lt;BR /&gt;Y.LABEL AS START,&lt;BR /&gt;X.LABEL AS LABEL&lt;BR /&gt;FROM UPDT%EVAL(&amp;amp;UP+1) X,&lt;BR /&gt;UPDT%EVAL(&amp;amp;UP+1) Y&lt;BR /&gt;WHERE (X.START EQ Y.START)&lt;BR /&gt;AND (Y.LABEL &amp;gt; X.LABEL)&lt;BR /&gt;ORDER BY KEY, START, LABEL;&lt;BR /&gt;QUIT;&lt;BR /&gt;DATA _NULL_;&lt;BR /&gt;CALL SYMPUT('LKOBS',&lt;BR /&gt;TRIM(LEFT(PUT(LINK,10.))));&lt;BR /&gt;SET LINK%EVAL(&amp;amp;LK+1) NOBS=LINK;&lt;BR /&gt;STOP;&lt;BR /&gt;RUN;&lt;BR /&gt;%PUT %STR( );&lt;BR /&gt;%PUT NOTE: DATA SET LINK%EVAL(&amp;amp;LK+1)&lt;BR /&gt;HAS &amp;amp;LKOBS OBSERVATION PAIRS.;&lt;BR /&gt;DATA _NULL_;&lt;BR /&gt;CALL SYMPUT('REOBS',&lt;BR /&gt;TRIM(LEFT(PUT(REPEAT,10.))));&lt;BR /&gt;SET REPEAT%EVAL(&amp;amp;RE+1) NOBS=REPEAT;&lt;BR /&gt;STOP;&lt;BR /&gt;RUN;&lt;BR /&gt;%PUT %STR( );&lt;BR /&gt;%PUT NOTE: DATA SET REPEAT%EVAL(&amp;amp;RE+1)&lt;BR /&gt;HAS &amp;amp;REOBS OBSERVATION PAIRS.;&lt;BR /&gt;%LET ITERS = %EVAL(&amp;amp;ITERS+1);&lt;BR /&gt;%LET INIFMTS_ = UPDT%EVAL(&amp;amp;UP+1);&lt;BR /&gt;%LET UP = %EVAL(&amp;amp;UP+2);&lt;BR /&gt;%LET LK = %EVAL(&amp;amp;LK+1);&lt;BR /&gt;%LET RE = %EVAL(&amp;amp;RE+1);&lt;BR /&gt;%END; /* END OF %DO %WHILE LOOP */&lt;BR /&gt;DATA _NULL_;&lt;BR /&gt;CALL SYMPUT('NEWOBS',&lt;BR /&gt;TRIM(LEFT(PUT(NEWOBS,10.))));&lt;BR /&gt;SET &amp;amp;INIFMTS_ NOBS=NEWOBS;&lt;BR /&gt;STOP;&lt;BR /&gt;RUN;&lt;BR /&gt;%PUT NOTE: TRANS MADE &amp;amp;ITERS ITERATIONS.;&lt;BR /&gt;%PUT NOTE: %EVAL(&amp;amp;OLDOBS - &amp;amp;NEWOBS)&lt;BR /&gt;DUPLICATE MAPPINGS WERE REMOVED.;&lt;BR /&gt;OPTIONS NOTES;&lt;BR /&gt;%PUT NOTE: SORTING &amp;amp;NEWOBS OBSERVATIONS IN&lt;BR /&gt;THE UPDATES DATA INTO &amp;amp;FINFMTS_..;&lt;BR /&gt;PROC SORT DATA = &amp;amp;INIFMTS_ OUT = &amp;amp;FINFMTS_&lt;BR /&gt;NODUPKEY;&lt;BR /&gt;BY START LABEL;&lt;BR /&gt;RUN;&lt;BR /&gt;%IF &amp;amp;NEWOBS NE 0 %THEN&lt;BR /&gt;%DO;&lt;BR /&gt;PROC FORMAT CNTLIN = &amp;amp;FINFMTS_;&lt;BR /&gt;DATA &amp;amp;OUTDATA_;&lt;BR /&gt;SET &amp;amp;INDATA_;&lt;BR /&gt;&amp;amp;TRANS_=PUT(&amp;amp;TRANS_,&amp;amp;FINFMTS_..);&lt;BR /&gt;RUN;&lt;BR /&gt;%END;&lt;BR /&gt;%ELSE&lt;BR /&gt;%DO;&lt;BR /&gt;PROC DATA SETS;&lt;BR /&gt;CHANGE &amp;amp;INDATA_ = &amp;amp;OUTDATA;&lt;BR /&gt;RUN;&lt;BR /&gt;%END;&lt;BR /&gt;%MEND TRANS;&lt;BR /&gt;%TRANS(INDATA_ = ALLDATA4,&lt;BR /&gt;OUTDATA_ = ALLDATA5,&lt;BR /&gt;INIFMTS_ = TRANSND0,&lt;BR /&gt;FINFMTS_ = TRANSND,&lt;BR /&gt;TRANS_ = NDKEY)&lt;BR /&gt;%GENFMTS(INDATA_ = ALLDATA5,&lt;BR /&gt;FMTS_ = TRANSNS,&lt;BR /&gt;KEY1_ = ND,&lt;BR /&gt;KEY2_ = NS)&lt;BR /&gt;%TRANS(INDATA_ = ALLDATA5,&lt;BR /&gt;OUTDATA_ = ALLDATA6,&lt;BR /&gt;INIFMTS_ = TRANSNS0,&lt;BR /&gt;FINFMTS_ = TRANSNS,&lt;BR /&gt;TRANS_ = NSKEY)&lt;BR /&gt;%GENFMTS(INDATA_ = ALLDATA6,&lt;BR /&gt;FMTS_ = TRANSSD,&lt;BR /&gt;KEY1_ = NS,&lt;BR /&gt;KEY2_ = SD)&lt;BR /&gt;%TRANS(INDATA_ = ALLDATA6,&lt;BR /&gt;OUTDATA_ = ALLDATA7,&lt;BR /&gt;INIFMTS_ = TRANSSD0,&lt;BR /&gt;FINFMTS_ = TRANSSD,&lt;BR /&gt;TRANS_ = SDKEY)&lt;BR /&gt;PROC SORT DATA = ALLDATA7;&lt;BR /&gt;BY SDKEY;&lt;BR /&gt;RUN;&lt;BR /&gt;DATA ALLDATA8(KEEP = ADNUM CLIENTID)/*remove keep statement if you want to*/;/* This step adds the client id */&lt;BR /&gt;SET ALLDATA7;&lt;BR /&gt;BY SDKEY;&lt;BR /&gt;IF FIRST.SDKEY THEN CLIENTID + 1;&lt;BR /&gt;RUN;&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
    <pubDate>Fri, 01 Feb 2013 12:37:34 GMT</pubDate>
    <dc:creator>Ayo_sas</dc:creator>
    <dc:date>2013-02-01T12:37:34Z</dc:date>
    <item>
      <title>Match on at least 2 keys</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Match-on-at-least-2-keys/m-p/93987#M257596</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;I'm trying to create data set WANT from HAVE based on the condition that there must be a match on at least 2keys. I have two approaches that I have tried. Thanks to some SAS information at &lt;A href="http://www2.sas.com/proceedings/sugi27/p075-27.pdf"&gt;www2.sas.com/proceedings/sugi27/p075-27.pdf&lt;/A&gt; The SQL approach finds the match but becomes a time consuming and resource intensive approach when dealing with large data set. Approach 2 does work but definitely a lengthy process and I find it a bit difficult to follow and replicate.&lt;/P&gt;&lt;P&gt;Question: 1) Anyone has a different (3rd) approach to solving this problem? OR&lt;BR /&gt;2) Could anyone provide an enhancement to approach 2 by adding a new variable country (‘US’ for all participants) to data set work.HAVE and generate a data set work.WANT with the condition that there’s a match on at least 2 keys. Note: The client_ID value should not change (I think). Thanks&lt;/P&gt;&lt;P&gt;&lt;BR /&gt;&lt;STRONG&gt;HAVE&lt;/STRONG&gt;&lt;/P&gt;&lt;P&gt;&lt;BR /&gt;ADNUM SSN NAME DOB &lt;BR /&gt;101 856116534 ABCD 18760323 &lt;BR /&gt;187 856176354 ABCD 18760323 &lt;BR /&gt;233 856176354 ABCD 18670323 &lt;BR /&gt;456 850176534 ABCD 18760323 &lt;BR /&gt;490 856176534 ABEF 18670323 &lt;BR /&gt;535 856176534 ABGF 18760323 &lt;BR /&gt;601 856176534 ABEF 18760323 &lt;BR /&gt;632 856176534 ABEE 18760323 &lt;BR /&gt;879 856116534 ABEF 18760323 &lt;BR /&gt;911 856176534 ABGF 18760323 &lt;BR /&gt;919 123456789 JOHN 19000224 &lt;BR /&gt;200 000089712 DAVE 20000212&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;BR /&gt;&lt;STRONG&gt;WANT (ALLDATA8)&lt;/STRONG&gt;&lt;/P&gt;&lt;P&gt;ADNUM SSN NAME DOB &lt;STRONG&gt;Client_id&lt;/STRONG&gt;&lt;BR /&gt;101 856116534 ABCD 18760323 3&lt;BR /&gt;187 856176354 ABCD 18760323 3&lt;BR /&gt;233 856176354 ABCD 18670323 3&lt;BR /&gt;456 850176534 ABCD 18760323 3&lt;BR /&gt;490 856176534 ABEF 18670323 3&lt;BR /&gt;535 856176534 ABGF 18760323 3&lt;BR /&gt;601 856176534 ABEF 18760323 3&lt;BR /&gt;632 856176534 ABEE 18760323 3&lt;BR /&gt;879 856116534 ABEF 18760323 3&lt;BR /&gt;911 856176534 ABGF 18760323 3&lt;BR /&gt;919 123456789 JOHN 19000224 2&lt;BR /&gt;200 000089712 DAVE 20000212 1&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp; &lt;BR /&gt;/* SQL approach */&lt;BR /&gt;PROC SQL;&lt;BR /&gt;CREATE TABLE work.match AS&lt;BR /&gt;SELECT X.ADNUM AS ADNUM1,&lt;BR /&gt;Y.ADNUM AS ADNUM2&lt;BR /&gt;FROM work.have X, work.have Y&lt;BR /&gt;WHERE ( (X.SSN EQ Y.SSN)&lt;BR /&gt;+ (X.NAME EQ Y.NAME)&lt;BR /&gt;+ (X.DOB EQ Y.DOB) ) &amp;gt;= 2&lt;BR /&gt;AND (X.ADNUM &amp;lt; Y.ADNUM)&lt;BR /&gt;ORDER BY ADNUM1, ADNUM2;&lt;BR /&gt;QUIT;&lt;/P&gt;&lt;P&gt;&lt;BR /&gt;/* Approach 2*/&lt;BR /&gt;DATA ALLDATA1 /*(KEEP = ADNUM NSID SDID NDID)*/;&lt;BR /&gt;SET work.have;/* imported data or created data set*/&lt;BR /&gt;LENGTH NSID $ 13 SDID $ 17 NDID $ 12&lt;BR /&gt;DOBC $ 8;&lt;BR /&gt;DOBC = TRIM(LEFT(COMPRESS(PUT(DOB,&lt;BR /&gt;BEST12.),'-')));&lt;BR /&gt;NSID = TRIM(NAME)||TRIM(SSN);&lt;BR /&gt;NDID = TRIM(NAME)||DOBC;&lt;BR /&gt;SDID = TRIM(SSN)||DOBC;&lt;BR /&gt;RUN;&lt;BR /&gt;%MACRO GENKEY(INDATA_ = , /* INPUT DATA */&lt;BR /&gt;OUTDATA_ = , /* OUTPUT DATA */&lt;BR /&gt;KEYID_ = /* BY VAR. */);&lt;BR /&gt;%LOCAL INDATA_ OUTDATA_ KEYID_;&lt;BR /&gt;PROC SORT DATA = &amp;amp;INDATA_;&lt;BR /&gt;BY &amp;amp;KEYID_.ID;&lt;BR /&gt;RUN;&lt;BR /&gt;DATA &amp;amp;OUTDATA_(DROP = &amp;amp;KEYID_.ID);&lt;BR /&gt;SET &amp;amp;INDATA_;&lt;BR /&gt;BY &amp;amp;KEYID_.ID;&lt;BR /&gt;IF FIRST.&amp;amp;KEYID_.ID THEN &amp;amp;KEYID_.KEY+1;&lt;BR /&gt;RUN;&lt;BR /&gt;%MEND GENKEY;&lt;BR /&gt;%GENKEY(INDATA_ = ALLDATA1,&lt;BR /&gt;OUTDATA_ = ALLDATA2,&lt;BR /&gt;KEYID_ = NS)&lt;BR /&gt;%GENKEY(INDATA_ = ALLDATA2,&lt;BR /&gt;OUTDATA_ = ALLDATA3,&lt;BR /&gt;KEYID_ = ND)&lt;BR /&gt;%GENKEY(INDATA_ = ALLDATA3,&lt;BR /&gt;OUTDATA_ = ALLDATA4,&lt;BR /&gt;KEYID_ = SD)&lt;BR /&gt;%MACRO GENFMTS(INDATA_ = , /* INPUT DATA */&lt;BR /&gt;FMTS_ = , /* FORMATS NAME */&lt;BR /&gt;KEY1_ = , /* WITHIN */&lt;BR /&gt;KEY2_ = /* TRANSLATE */);&lt;BR /&gt;%LOCAL INDATA_ FMTS_ KEY1_ KEY2_;&lt;BR /&gt;PROC SORT DATA = &amp;amp;INDATA_;&lt;BR /&gt;BY &amp;amp;KEY1_.KEY &amp;amp;KEY2_.KEY;&lt;BR /&gt;RUN;&lt;BR /&gt;DATA &amp;amp;FMTS_.0(KEEP = FMTNAME START LABEL&lt;BR /&gt;KEY);&lt;BR /&gt;SET &amp;amp;INDATA_;&lt;BR /&gt;BY &amp;amp;KEY1_.KEY;&lt;BR /&gt;RETAIN FMTNAME "&amp;amp;FMTS_" &amp;amp;KEY2_.KEYF;&lt;BR /&gt;IF FIRST.&amp;amp;KEY1_.KEY&lt;BR /&gt;THEN &amp;amp;KEY2_.KEYF = &amp;amp;KEY2_.KEY;&lt;BR /&gt;IF &amp;amp;KEY2_.KEY NE &amp;amp;KEY2_.KEYF THEN&lt;BR /&gt;DO;&lt;BR /&gt;START = &amp;amp;KEY2_.KEY;&lt;BR /&gt;LABEL = &amp;amp;KEY2_.KEYF;&lt;BR /&gt;KEY + 1;&lt;BR /&gt;OUTPUT;&lt;BR /&gt;END;&lt;BR /&gt;RUN;&lt;BR /&gt;PROC SORT DATA = &amp;amp;FMTS_.0 NODUPKEY;&lt;BR /&gt;BY START LABEL;&lt;BR /&gt;RUN;&lt;BR /&gt;%MEND GENFMTS;&lt;BR /&gt;%GENFMTS(INDATA_ = ALLDATA4,&lt;BR /&gt;FMTS_ = TRANSND,&lt;BR /&gt;KEY1_ = SD,&lt;BR /&gt;KEY2_ = ND) /* Tested to this level */&lt;BR /&gt;%MACRO TRANS(INDATA_ = ,&lt;BR /&gt;OUTDATA_ = ,&lt;BR /&gt;INIFMTS_ = ,&lt;BR /&gt;FINFMTS_ = ,&lt;BR /&gt;TRANS_ = );&lt;BR /&gt;%LOCAL&lt;BR /&gt;INDATA_ /* INPUT DATA SET */&lt;BR /&gt;OUTDATA_ /* OUTPUT DATA SET */&lt;BR /&gt;INIFMTS_ /* INITIAL FORMATS */&lt;BR /&gt;FINFMTS_ /* FINAL FORMATS */&lt;BR /&gt;TRANS_ /* **KEY TO BE TRANSLATED */&lt;BR /&gt;NEWOBS /* OBS. IN INITIAL FORMATS */&lt;BR /&gt;OLDOBS /* OBS. IN FINAL FORMATS */&lt;BR /&gt;LKOBS /* NUM OF LINK CASES TO BE&lt;BR /&gt;UPDATED IN EACH ITERATION */&lt;BR /&gt;REOBS /* NUM OF REPEAT CASES TO BE&lt;BR /&gt;UPDATED IN EACH ITERATION */&lt;BR /&gt;ITERS /* NUM OF ITERATIONS */&lt;BR /&gt;UP /* SERIES NUMBER FOR THE&lt;BR /&gt;TEMPORARY UPDATE DATA SET */&lt;BR /&gt;LK /* SERIES NUMBER FOR THE&lt;BR /&gt;TEMPORARY LINK DATA SET */&lt;BR /&gt;RE /* SERIES NUMBER FOR THE&lt;BR /&gt;TEMPORARY REPEAT DATA SET */&lt;BR /&gt;;&lt;BR /&gt;%LET UP = 1;&lt;BR /&gt;%LET LK = 1;&lt;BR /&gt;%LET RE = 1;&lt;BR /&gt;%LET ITERS = 0;&lt;BR /&gt;DATA _NULL_;&lt;BR /&gt;CALL SYMPUT('OLDOBS',&lt;BR /&gt;TRIM(LEFT(PUT(OLDOBS,10.))));&lt;BR /&gt;SET &amp;amp;INIFMTS_ NOBS = OLDOBS;&lt;BR /&gt;STOP;&lt;BR /&gt;RUN;&lt;BR /&gt;%PUT %STR( );&lt;BR /&gt;%PUT NOTE: DATA SET &amp;amp;INIFMTS_ HAS &amp;amp;OLDOBS&lt;BR /&gt;OBSERVATION PAIRS.;&lt;BR /&gt;PROC SQL;&lt;BR /&gt;CREATE TABLE LINK&amp;amp;LK AS&lt;BR /&gt;SELECT Y.KEY AS KEY,&lt;BR /&gt;Y.START AS START,&lt;BR /&gt;X.LABEL AS LABEL&lt;BR /&gt;FROM &amp;amp;INIFMTS_ X, &amp;amp;INIFMTS_ Y&lt;BR /&gt;WHERE X.START EQ Y.LABEL&lt;BR /&gt;ORDER BY KEY, START, LABEL;&lt;BR /&gt;QUIT;&lt;BR /&gt;PROC SQL;&lt;BR /&gt;CREATE TABLE REPEAT&amp;amp;RE AS&lt;BR /&gt;SELECT Y.KEY AS KEY,&lt;BR /&gt;Y.LABEL AS START,&lt;BR /&gt;X.LABEL AS LABEL&lt;BR /&gt;FROM &amp;amp;INIFMTS_ X, &amp;amp;INIFMTS_ Y&lt;BR /&gt;WHERE (X.START EQ Y.START)&lt;BR /&gt;AND (Y.LABEL &amp;gt; X.LABEL)&lt;BR /&gt;ORDER BY KEY, START, LABEL;&lt;BR /&gt;QUIT;&lt;BR /&gt;DATA _NULL_;&lt;BR /&gt;CALL SYMPUT('LKOBS',&lt;BR /&gt;TRIM(LEFT(PUT(LINK,10.))));&lt;BR /&gt;SET LINK&amp;amp;LK NOBS = LINK;&lt;BR /&gt;STOP;&lt;BR /&gt;RUN;&lt;BR /&gt;%PUT %STR( );&lt;BR /&gt;%PUT NOTE: DATA SET LINK&amp;amp;LK HAS &amp;amp;LKOBS&lt;BR /&gt;OBSERVATION PAIRS.;&lt;BR /&gt;DATA _NULL_;&lt;BR /&gt;CALL SYMPUT('REOBS',&lt;BR /&gt;TRIM(LEFT(PUT(REPEAT,10.))));&lt;BR /&gt;SET REPEAT&amp;amp;RE NOBS = REPEAT;&lt;BR /&gt;STOP;&lt;BR /&gt;RUN;&lt;BR /&gt;%PUT %STR( );&lt;BR /&gt;%PUT NOTE: DATA SET REPEAT&amp;amp;RE HAS &amp;amp;REOBS&lt;BR /&gt;OBSERVATION PAIRS.;&lt;BR /&gt;%DO %WHILE ((&amp;amp;LKOBS NE 0)&lt;BR /&gt;OR (&amp;amp;REOBS NE 0));&lt;BR /&gt;PROC SORT DATA = &amp;amp;INIFMTS_;&lt;BR /&gt;BY KEY;&lt;BR /&gt;RUN;&lt;BR /&gt;DATA UPDT&amp;amp;UP;&lt;BR /&gt;UPDATE &amp;amp;INIFMTS_ LINK&amp;amp;LK;&lt;BR /&gt;BY KEY;&lt;BR /&gt;RUN;&lt;BR /&gt;DATA UPDT%EVAL(&amp;amp;UP+1);&lt;BR /&gt;UPDATE UPDT&amp;amp;UP REPEAT&amp;amp;RE;&lt;BR /&gt;BY KEY;&lt;BR /&gt;RUN;&lt;BR /&gt;PROC SORT DATA = UPDT%EVAL(&amp;amp;UP+1)&lt;BR /&gt;NODUPKEY;&lt;BR /&gt;BY START LABEL;&lt;BR /&gt;RUN;&lt;BR /&gt;PROC SQL;&lt;BR /&gt;CREATE TABLE LINK%EVAL(&amp;amp;LK+1) AS&lt;BR /&gt;SELECT Y.KEY AS KEY,&lt;BR /&gt;Y.START AS START,&lt;BR /&gt;X.LABEL AS LABEL&lt;BR /&gt;FROM UPDT%EVAL(&amp;amp;UP+1) X,&lt;BR /&gt;UPDT%EVAL(&amp;amp;UP+1) Y&lt;BR /&gt;WHERE X.START EQ Y.LABEL&lt;BR /&gt;ORDER BY KEY, START, LABEL;&lt;BR /&gt;QUIT;&lt;BR /&gt;PROC SQL;&lt;BR /&gt;CREATE TABLE REPEAT%EVAL(&amp;amp;RE+1) AS&lt;BR /&gt;SELECT Y.KEY AS KEY,&lt;BR /&gt;Y.LABEL AS START,&lt;BR /&gt;X.LABEL AS LABEL&lt;BR /&gt;FROM UPDT%EVAL(&amp;amp;UP+1) X,&lt;BR /&gt;UPDT%EVAL(&amp;amp;UP+1) Y&lt;BR /&gt;WHERE (X.START EQ Y.START)&lt;BR /&gt;AND (Y.LABEL &amp;gt; X.LABEL)&lt;BR /&gt;ORDER BY KEY, START, LABEL;&lt;BR /&gt;QUIT;&lt;BR /&gt;DATA _NULL_;&lt;BR /&gt;CALL SYMPUT('LKOBS',&lt;BR /&gt;TRIM(LEFT(PUT(LINK,10.))));&lt;BR /&gt;SET LINK%EVAL(&amp;amp;LK+1) NOBS=LINK;&lt;BR /&gt;STOP;&lt;BR /&gt;RUN;&lt;BR /&gt;%PUT %STR( );&lt;BR /&gt;%PUT NOTE: DATA SET LINK%EVAL(&amp;amp;LK+1)&lt;BR /&gt;HAS &amp;amp;LKOBS OBSERVATION PAIRS.;&lt;BR /&gt;DATA _NULL_;&lt;BR /&gt;CALL SYMPUT('REOBS',&lt;BR /&gt;TRIM(LEFT(PUT(REPEAT,10.))));&lt;BR /&gt;SET REPEAT%EVAL(&amp;amp;RE+1) NOBS=REPEAT;&lt;BR /&gt;STOP;&lt;BR /&gt;RUN;&lt;BR /&gt;%PUT %STR( );&lt;BR /&gt;%PUT NOTE: DATA SET REPEAT%EVAL(&amp;amp;RE+1)&lt;BR /&gt;HAS &amp;amp;REOBS OBSERVATION PAIRS.;&lt;BR /&gt;%LET ITERS = %EVAL(&amp;amp;ITERS+1);&lt;BR /&gt;%LET INIFMTS_ = UPDT%EVAL(&amp;amp;UP+1);&lt;BR /&gt;%LET UP = %EVAL(&amp;amp;UP+2);&lt;BR /&gt;%LET LK = %EVAL(&amp;amp;LK+1);&lt;BR /&gt;%LET RE = %EVAL(&amp;amp;RE+1);&lt;BR /&gt;%END; /* END OF %DO %WHILE LOOP */&lt;BR /&gt;DATA _NULL_;&lt;BR /&gt;CALL SYMPUT('NEWOBS',&lt;BR /&gt;TRIM(LEFT(PUT(NEWOBS,10.))));&lt;BR /&gt;SET &amp;amp;INIFMTS_ NOBS=NEWOBS;&lt;BR /&gt;STOP;&lt;BR /&gt;RUN;&lt;BR /&gt;%PUT NOTE: TRANS MADE &amp;amp;ITERS ITERATIONS.;&lt;BR /&gt;%PUT NOTE: %EVAL(&amp;amp;OLDOBS - &amp;amp;NEWOBS)&lt;BR /&gt;DUPLICATE MAPPINGS WERE REMOVED.;&lt;BR /&gt;OPTIONS NOTES;&lt;BR /&gt;%PUT NOTE: SORTING &amp;amp;NEWOBS OBSERVATIONS IN&lt;BR /&gt;THE UPDATES DATA INTO &amp;amp;FINFMTS_..;&lt;BR /&gt;PROC SORT DATA = &amp;amp;INIFMTS_ OUT = &amp;amp;FINFMTS_&lt;BR /&gt;NODUPKEY;&lt;BR /&gt;BY START LABEL;&lt;BR /&gt;RUN;&lt;BR /&gt;%IF &amp;amp;NEWOBS NE 0 %THEN&lt;BR /&gt;%DO;&lt;BR /&gt;PROC FORMAT CNTLIN = &amp;amp;FINFMTS_;&lt;BR /&gt;DATA &amp;amp;OUTDATA_;&lt;BR /&gt;SET &amp;amp;INDATA_;&lt;BR /&gt;&amp;amp;TRANS_=PUT(&amp;amp;TRANS_,&amp;amp;FINFMTS_..);&lt;BR /&gt;RUN;&lt;BR /&gt;%END;&lt;BR /&gt;%ELSE&lt;BR /&gt;%DO;&lt;BR /&gt;PROC DATA SETS;&lt;BR /&gt;CHANGE &amp;amp;INDATA_ = &amp;amp;OUTDATA;&lt;BR /&gt;RUN;&lt;BR /&gt;%END;&lt;BR /&gt;%MEND TRANS;&lt;BR /&gt;%TRANS(INDATA_ = ALLDATA4,&lt;BR /&gt;OUTDATA_ = ALLDATA5,&lt;BR /&gt;INIFMTS_ = TRANSND0,&lt;BR /&gt;FINFMTS_ = TRANSND,&lt;BR /&gt;TRANS_ = NDKEY)&lt;BR /&gt;%GENFMTS(INDATA_ = ALLDATA5,&lt;BR /&gt;FMTS_ = TRANSNS,&lt;BR /&gt;KEY1_ = ND,&lt;BR /&gt;KEY2_ = NS)&lt;BR /&gt;%TRANS(INDATA_ = ALLDATA5,&lt;BR /&gt;OUTDATA_ = ALLDATA6,&lt;BR /&gt;INIFMTS_ = TRANSNS0,&lt;BR /&gt;FINFMTS_ = TRANSNS,&lt;BR /&gt;TRANS_ = NSKEY)&lt;BR /&gt;%GENFMTS(INDATA_ = ALLDATA6,&lt;BR /&gt;FMTS_ = TRANSSD,&lt;BR /&gt;KEY1_ = NS,&lt;BR /&gt;KEY2_ = SD)&lt;BR /&gt;%TRANS(INDATA_ = ALLDATA6,&lt;BR /&gt;OUTDATA_ = ALLDATA7,&lt;BR /&gt;INIFMTS_ = TRANSSD0,&lt;BR /&gt;FINFMTS_ = TRANSSD,&lt;BR /&gt;TRANS_ = SDKEY)&lt;BR /&gt;PROC SORT DATA = ALLDATA7;&lt;BR /&gt;BY SDKEY;&lt;BR /&gt;RUN;&lt;BR /&gt;DATA ALLDATA8(KEEP = ADNUM CLIENTID)/*remove keep statement if you want to*/;/* This step adds the client id */&lt;BR /&gt;SET ALLDATA7;&lt;BR /&gt;BY SDKEY;&lt;BR /&gt;IF FIRST.SDKEY THEN CLIENTID + 1;&lt;BR /&gt;RUN;&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Fri, 01 Feb 2013 12:37:34 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Match-on-at-least-2-keys/m-p/93987#M257596</guid>
      <dc:creator>Ayo_sas</dc:creator>
      <dc:date>2013-02-01T12:37:34Z</dc:date>
    </item>
    <item>
      <title>Re: Match on at least 2 keys</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Match-on-at-least-2-keys/m-p/93988#M257597</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;wow...sort of difficult to follow...&lt;/P&gt;&lt;P&gt;best I could do was build on the first approach.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;data HAVE;&lt;/P&gt;&lt;P&gt;input ADNUM SSN&amp;nbsp; NAME $ DOB;&lt;/P&gt;&lt;P&gt;format dob datetime20;&lt;/P&gt;&lt;P&gt;match1 = catx('',put(ssn,z9.),trim(name));&lt;/P&gt;&lt;P&gt;match2=catx('',put(ssn,z9.),put(dob,best12.));&lt;/P&gt;&lt;P&gt;match3=catx('',trim(name),put(dob,best12.));&lt;/P&gt;&lt;P&gt;cards;&lt;/P&gt;&lt;P&gt;101 856116534 ABCD 18760323&lt;/P&gt;&lt;P&gt;187 856176354 ABCD 18760323&lt;/P&gt;&lt;P&gt;233 856176354 ABCD 18670323&lt;/P&gt;&lt;P&gt;456 850176534 ABCD 18760323&lt;/P&gt;&lt;P&gt;490 856176534 ABEF 18670323&lt;/P&gt;&lt;P&gt;535 856176534 ABGF 18760323&lt;/P&gt;&lt;P&gt;601 856176534 ABEF 18760323&lt;/P&gt;&lt;P&gt;632 856176534 ABEE 18760323&lt;/P&gt;&lt;P&gt;879 856116534 ABEF 18760323&lt;/P&gt;&lt;P&gt;911 856176534 ABGF 18760323&lt;/P&gt;&lt;P&gt;919 123456789 JOHN 19000224&lt;/P&gt;&lt;P&gt;200 000089712 DAVE 20000212&lt;/P&gt;&lt;P&gt;;&lt;/P&gt;&lt;P&gt;run;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;proc sql;&lt;/P&gt;&lt;P&gt;create table want as&lt;/P&gt;&lt;P&gt;select&amp;nbsp;&amp;nbsp; &lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; t1.adnum as adnum1&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ,t2.adnum as adnum2&lt;/P&gt;&lt;P&gt;from&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; have t1&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; inner join have t2&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; on (t1.match1 = t2.match1 or t1.match2=t2.match2 or t1.match3=t2.match3)&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; and t1.adnum &amp;lt; t2.adnum;&lt;/P&gt;&lt;P&gt;quit;&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Fri, 01 Feb 2013 13:23:43 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Match-on-at-least-2-keys/m-p/93988#M257597</guid>
      <dc:creator>DBailey</dc:creator>
      <dc:date>2013-02-01T13:23:43Z</dc:date>
    </item>
  </channel>
</rss>

