Problems / Returning vs New Users / Editorial
SELECT DISTINCT user_id, DATE_TRUNC('day', event_time)
MIN(day) OVER (PARTITION BY user_id)
day = first_day
day > first_day
new + returning = DAU
"New vs returning" is a comparison between a row's value and a per-partition aggregate — the exact shape window functions exist for. The equivalent join formulation (daily activity ⋈ first-day-per-user) is longer and easy to get subtly wrong (joining back at the event grain re-introduces duplicates). When a classification needs *the row* and *a fact about the row's group* side by side, reach for agg OVER (PARTITION BY group) before reaching for a self-join.
agg OVER (PARTITION BY group)
Solve Returning vs New Users yourself →