Premium problem100. Recency-Weighted Multi-Touch Attribution

Hard Locked

touches(user_id, channel, touched_at) and conversions(conversion_id, user_id, converted_at, revenue)

Split each conversion's revenue across the touches in the 14 days up to and including it. A touch d whole days before the conversion gets raw weight 1 / (1 + d), the weights are normalised so they sum to 1 within that conversion, and revenue is allocated in proportion. A conversion with no eligible touch gives all of its revenue to 'direct'.

Return channel and allocated_revenue rounded to two decimals, ordered by channel.

Every conversion's revenue is accounted for exactly once, so the allocated total equals the revenue total. Normalising across the wrong partition is what breaks that, and it is worth checking the sum when you are done.

Tables

conversions

conversion_id  user_id  converted_at         revenue
-------------  -------  -------------------  -------
1              1        2026-06-10 10:00:00  120.00
2              2        2026-06-10 10:00:00  60.00
3              3        2026-06-10 10:00:00  40.00

touches

user_id  channel  touched_at
-------  -------  -------------------
1        search   2026-06-10 08:00:00
1        email    2026-06-06 08:00:00
1        social   2026-05-21 08:00:00
2        email    2026-06-09 08:00:00
2        email    2026-06-08 08:00:00
3        display  2026-01-01 08:00:00

Expected result

channel  allocated_revenue
-------  -----------------
direct   40.00
email    80.00
search   100.00

Premium problem

This one's part of Premium. Unlock the full MySQL track plus every other premium problem on the site.

Write one SELECT query