Problems / First and Last Order Pivot / Editorial
Per customer we need four values taken from two specific rows — the earliest and the latest order:
MIN(order_ts)
MAX(order_ts)
arg_min(channel, order_ts)
channel
order_ts
arg_max
min_by
max_by
GROUP BY customer_id
ORDER BY customer_id
In SQLFrame/PySpark there is no native arg_min; F.expr("arg_min(channel, order_ts)") inside .agg() reaches the engine function. The classical portable alternative is row_number() over (PARTITION BY customer_id ORDER BY order_ts) ascending and descending, then conditional aggregation on the rn = 1 rows.
arg_min
F.expr("arg_min(channel, order_ts)")
.agg()
row_number()
(PARTITION BY customer_id ORDER BY order_ts)
rn = 1
MIN(channel) is the classic wrong answer: it takes the alphabetical minimum, which has nothing to do with time — customer 101's first order came through 'web', but their alphabetically-first channel is 'app'. arg_min / arg_max express "the value of column A at the extreme of column B" in a single aggregate — the same pattern as "top product per store", with no window function in sight.
MIN(channel)
Solve First and Last Order Pivot yourself →