the where clause works at the row level. if you want to filter on aggregate values, then the were needs to use a having or a sub select. ... where (select count...) ...) < 5
.
your other option is use CTE:
WITH Totals as
(
SELECT MRNumber, tblPtmstr1.PatientLastName, tblPtmstr1.PatientFirstName, tblPtmstr1.PatientDOB,
COUNT(CASE WHEN vaccine = 'DTaP' THEN 1 END) AS DTaP,
COUNT(CASE WHEN vaccine = 'IPV' THEN 1 END) AS IPV,
COUNT(CASE WHEN vaccine = 'MMR' THEN 1 END) AS MMR,
COUNT(CASE WHEN vaccine Like '%Hib%' THEN 1 END) AS Hib,
COUNT(CASE WHEN vaccine = 'Hep B, adolescent or pediatric' THEN 1 END) AS HepB,
COUNT(CASE WHEN vaccine = 'varicella' THEN 1 END) AS VZW,
COUNT(CASE WHEN vaccine Like '%PCV%' THEN 1 END) AS PCV
FROM tbl_Log_ImmunizationRegistry AS tblVaccines
LEFT JOIN tblPtmstr1 on tblVaccines.MRNumber = tblPtmstr1.PatientID
Where Convert(date, tblVaccines.PatientDOB) Between '01/01/2022 12:00 am' and '12/31/2023 11:59 pm'
GROUP BY MRNumber, tblPtmstr1.PatientLastName, tblPtmstr1.PatientFirstName, tblPtmstr1.PatientDOB
)
select *
from Totals
where DTaP < 5;