SAS (Base SAS)+
*==============================================================================;
* Create sample ADSL with safety flag;
*==============================================================================;
data adsl;
input usubjid $ trt01p $ saffl $;
datalines;
SUBJ001 Placebo Y
SUBJ002 DrugA Y
SUBJ003 Placebo N
SUBJ004 DrugA Y
SUBJ005 Placebo Y
;
run;
*==============================================================================;
* Create sample ADAE;
*==============================================================================;
data adae;
input usubjid $ aedecod $12. aesev $;
datalines;
SUBJ001 Headache MILD
SUBJ002 Nausea MODERATE
SUBJ003 Fatigue MILD
SUBJ003 Dizziness SEVERE
SUBJ004 Rash MILD
SUBJ005 Cough MILD
;
run;
*==============================================================================;
* Subquery: keep AEs only for safety-population subjects;
*==============================================================================;
proc sql;
create table ae_saf as
select *
from adae
where usubjid in
(select usubjid from adsl where saffl = 'Y');
quit;
proc print data=ae_saf; title "AEs in Safety Population"; run;
*==============================================================================;
* NOT IN subquery: AEs for subjects NOT in safety population;
*==============================================================================;
proc sql;
create table ae_nonsaf as
select *
from adae
where usubjid not in
(select usubjid from adsl where saffl = 'Y');
quit;
proc print data=ae_nonsaf; title "AEs NOT in Safety Population"; run;- The subquery
(SELECT usubjid FROM adsl WHERE saffl = 'Y')builds a list of subject IDs in the safety population. - The outer query uses
WHERE usubjid IN (...)to keep only ADAE rows whose USUBJID appears in that list. - This is a filter-only operation β no columns from ADSL are added to the result, unlike a join.
- SUBJ003 has
saffl = 'N', so both of their AE records (Fatigue and Dizziness) are excluded fromae_saf. - The
NOT INvariant reverses the logic β it keeps AEs for subjects outside the safety population, which is useful for data-quality checks. - Subqueries are more efficient than a full join when we only need to filter and do not need columns from the lookup table.
- After running, we confirm
ae_safhas 4 rows (SUBJ001, SUBJ002, SUBJ004, SUBJ005) andae_nonsafhas 2 rows (SUBJ003).