SAS (Base SAS)+
*==============================================================================;
* Create sample ADSL (subject-level);
*==============================================================================;
data adsl;
input usubjid $ trt01p $;
datalines;
SUBJ001 Placebo
SUBJ002 DrugA
SUBJ003 Placebo
SUBJ004 DrugA
;
run;
*==============================================================================;
* Create sample ADAE (event-level, SUBJ004 has no AEs, SUBJ005 not in ADSL);
*==============================================================================;
data adae;
input usubjid $ aedecod $20. aesev $;
datalines;
SUBJ001 Headache MILD
SUBJ001 Nausea MODERATE
SUBJ002 Fatigue MILD
SUBJ003 Dizziness SEVERE
SUBJ005 Rash MILD
;
run;
*==============================================================================;
* LEFT JOIN: keep all AE records, add treatment from ADSL;
*==============================================================================;
proc sql;
create table ae_left as
select a.*,
b.trt01p
from adae as a
left join adsl as b
on a.usubjid = b.usubjid;
quit;
*==============================================================================;
* INNER JOIN: keep only AEs that match a subject in ADSL;
*==============================================================================;
proc sql;
create table ae_inner as
select a.*,
b.trt01p
from adae as a
inner join adsl as b
on a.usubjid = b.usubjid;
quit;
*==============================================================================;
* FULL JOIN: keep everything from both sides;
*==============================================================================;
proc sql;
create table ae_full as
select coalesce(a.usubjid, b.usubjid) as usubjid,
a.aedecod,
a.aesev,
b.trt01p
from adae as a
full join adsl as b
on a.usubjid = b.usubjid;
quit;
proc print data=ae_left; title "LEFT JOIN"; run;
proc print data=ae_inner; title "INNER JOIN"; run;
proc print data=ae_full; title "FULL JOIN"; run;- A
LEFT JOINkeeps every row from the left table (ADAE) and brings in matching columns from the right table (ADSL). Unmatched AE rows get missing values for treatment. - SUBJ005 has an AE but is not in ADSL — the left join keeps that row with
trt01pset to missing. - An
INNER JOINkeeps only rows that match on both sides — SUBJ005’s AE is dropped because there is no matching ADSL record. - A
FULL JOINkeeps everything from both tables. SUBJ004 (in ADSL, no AEs) appears with missing AE columns; SUBJ005 (AE, not in ADSL) appears with missing treatment. - We use
coalesce(a.usubjid, b.usubjid)in the full join to fill the USUBJID from whichever side is non-missing. - The alias
aandbkeep the SQL readable —a.*means "all columns from the AE table." - After running, we compare: left join has 5 rows, inner join has 4 rows (SUBJ005 dropped), full join has 6 rows (SUBJ004 added).