If you can guarantee that there is only one row per activity per pat_Name then you can safely use an aggregate function to get the App_dtTm for each activity for each pat_name without fear of missing data. It also doesn't matter whether you use MIN or MAX if there are no duplicates.
SELECT s.Pat_Name,
Consult = MAX(CASE WHEN s.Activity = '123' THEN s.App_DtTm END),
SIM = MAX(CASE WHEN s.Activity = '456' THEN s.App_DtTm END),
PLANNING = MAX(CASE WHEN s.Activity = '789' THEN s.App_DtTm END),
TreatmentStart = MAX(CASE WHEN s.SysDefStatus = 'SC' THEN s.App_DtTm END),
TreatmentFinished = MAX(CASE WHEN s.SysDefStatus = 'FC' THEN s.App_DtTm END)
FROM vw_Schedule s
WHERE s.Activity IN ('123', '456', '789')
OR s.SysDefStatus IN ('SC', 'FC')
GROUP BY s.Pat_Name;
If you could have duplicate dates for a single activity then it will make a difference whether you us MIN or MAX.
To get the days between activity, you can move the above query to a common table expression (or subquery if you prefer) and simply reference the columns you have created:
WITH T AS
( SELECT s.Pat_Name,
Consult = MAX(CASE WHEN s.Activity = '123' THEN s.App_DtTm END),
SIM = MAX(CASE WHEN s.Activity = '456' THEN s.App_DtTm END),
PLANNING = MAX(CASE WHEN s.Activity = '789' THEN s.App_DtTm END),
TreatmentStart = MAX(CASE WHEN s.SysDefStatus = 'SC' THEN s.App_DtTm END),
TreatmentFinished = MAX(CASE WHEN s.SysDefStatus = 'FC' THEN s.App_DtTm END)
FROM vw_Schedule s
WHERE s.Activity IN ('123', '456', '789')
OR s.SysDefStatus IN ('SC', 'FC')
GROUP BY s.Pat_Name
)
SELECT Pat_Name,
Consult,
Days = DATEDIFF(DAY, Consult, SIM),
SIM,
Days = DATEDIFF(DAY, SIM, PLANNING),
PLANNING,
Days = DATEDIFF(DAY, PLANNING, TreatmentStart),
TreatmentStart,
Days = DATEDIFF(DAY, TreatmentStart, TreatmentFinish),
TreatmentFinish
FROM T;