As asked
Write SQL to find each user's first and last purchase date and the days between them. Use window functions.
Sample answer outline
Use FIRST_VALUE and LAST_VALUE partitioned by user_id, ordered by purchase_date. Be careful with the LAST_VALUE default frame, which is ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW; you need ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING to get the actual last. Alternative: MIN/MAX in an aggregation, then join back. Window function version is more flexible if you need other per-user attributes alongside.
Reference implementation (sql)
select distinct
user_id,
first_value(purchase_date) over (
partition by user_id order by purchase_date
rows between unbounded preceding and unbounded following
) as first_purchase,
last_value(purchase_date) over (
partition by user_id order by purchase_date
rows between unbounded preceding and unbounded following
) as last_purchase,
date_diff(
last_value(purchase_date) over (
partition by user_id order by purchase_date
rows between unbounded preceding and unbounded following
),
first_value(purchase_date) over (
partition by user_id order by purchase_date
rows between unbounded preceding and unbounded following
),
day
) as days_between
from purchases;Expect these follow-ups
- What is the difference between RANK, DENSE_RANK, and ROW_NUMBER?
- How would you compute a 7-day rolling sum of revenue per user?
- When is a self-join cleaner than a window function?