WITH u AS (
SELECT o.user_id, SUM(i.price * o.quantity) AS gmv
FROM orders o
JOIN items i ON i.item_id = o.item_id
WHERE o.status = 'completed'
GROUP BY o.user_id
),
tiled AS (
SELECT user_id, gmv,
NTILE(5) OVER(ORDER BY gmv DESC) AS tile5
FROM u
)
SELECT
ROUND(SUM(CASE WHEN tile5=1 THEN gmv ELSE 0 END) / NULLIF(SUM(gmv),0) * 100, 2)
AS top20_share_pct
FROM tiled;