task Cohorts & retention · hard
Checkout review 4: find later recoveries
An abandoned session contains checkout but no full ordered conversion. Find abandoned sessions with a same-cart purchase in a strictly later session within 24 hours of a checkout in the abandoned session. Return shopper_id, abandoned_session, recovery_session and recovery_minutes.
what to return
- Columns
shopper_idabandoned_sessionrecovery_sessionrecovery_minutesin this order- Rows
- 2 rows · in the order asked
- Watch for
- This stage starts from the original event tables in a fresh database. Recompute any intermediate results; nothing is carried over from earlier stages.
- Deduplicate globally by event_key, keeping the smallest id; a retry may have a conflicting payload.
- Use (occurred_at, id) as the total event order; equal timestamps follow id order. All times are UTC.
- A shopper starts a session at the first canonical event or after a gap strictly greater than 30 minutes from their previous canonical event. Exactly 30 minutes stays in the same session; midnight alone does not split it.
- Session numbers start at 1 per shopper and include every event type, including heartbeat and purchase-only sessions.
- A converted session has a view → checkout → purchase in that order, with all three events for the same shopper/cart within the session. Use the total event order. No extra view-to-purchase time limit applies.
- A recovery needs a purchase only; the later session need not repeat the view/checkout funnel. Match shopper and cart. The 24-hour bound is inclusive.
- Choose the earliest qualifying later purchase per abandoned session, then the latest qualifying checkout for that purchase. Return one row per recovered abandoned session, rounded minutes to two decimals, ordered by shopper_id,abandoned_session.
- Skill
- Distinguish same-session conversion from later recovery. Refresher: Sessionize an event stream →
expected result
Your query should return exactly these columns and values. Run it and compare.
expected result2 rows · in this order
| shopper_id | abandoned_session | recovery_session | recovery_minutes |
|---|---|---|---|
| 1 | 2 | 4 | 1375 |
| 5 | 1 | 2 | 45 |
all 2 rows
data you can query
Sample rows from each table. Each column shows its type underneath; → marks a link to another table.
market_web_events7 columns · 38 rows
| idinteger · key | event_keytext | shopper_idinteger → shoppers | occurred_attext | event_typetext | channeltext | cart_idtext |
|---|---|---|---|---|---|---|
| 1 | a1 | 1 | 2025-05-01 09:00:00 | view | A | |
| 2 | a2 | 1 | 2025-05-01 09:05:00 | checkout | direct | A |
| 3 | a3 | 1 | 2025-05-01 09:10:00 | purchase | direct | A |
| 4 | a3 | 1 | 2025-05-01 09:10:00 | purchase | direct | A |
| 5 | b1 | 1 | 2025-05-01 10:00:00 | view | search | B |
showing 5 of 38 rows
solution.sql
Hints and the answer are always available. Using them counts the question as solved with help.