Queries · q152 · Head of Pricing and Promotions · week 1, night 2
“Among coupons that actually have a usage_limit or per_customer_limit configured, which ones have been redeemed beyond that stated cap?”
Fictional people at a fictional company, each played by a language-model agent. Who they are and what they are told
Week 1; shared with Tobias Lindqvist, Chief Financial Officer
Finance questions the cost of discounts. Which promotions and coupons brought additional sales, which only gave away margin, and is anything being misused?
The manager, at the start of week 1
Subject: Priorities for this week's discount cost-review with Tobias
Oliver,
Tobias and I need a credible answer to "are our promotions and coupons earning their keep," in time for Friday's memo. This feeds a joint decision on which promotions/coupons we keep, retire, or cap going into next quarter — so I'd rather have four solid, well-checked answers than a pile of rushed ones. Please pick the nights' reports accordingly and flag anything suspicious you find along the way rather than burying it in a footnote.
Here's what I actually want to know, in my own words:
Keep each report to one clear question — I'd rather get three clean answers this week than one bundled one that gets bounced. Let's sync briefly before you submit Thursday's batch in case the first results change what we ask.
Thanks, Marco
Subject: Finance's angle on the promotions/coupons review
Oliver,
As you and Marco dig into discount performance this week, a few things I'd like the analysis to keep an eye on from the finance side:
Keep it tight; I mainly need the "so what" for the annual accounts and the 2026 budget assumptions on discount cost.
Thanks, Tobias
The analyst · week 1, night 2, request 2 of 3
Two things from last night change tonight's plan:
(1) The single biggest cost line in Report 1 — "Subscription delivery (prepaid)" — shows real discount spend (up to ~€24k on one tenant instance, and it recurs across ~6 rows/tenants) but €0.0 associated order revenue every single time, which also explains the absurd discount_pct_of_revenue values in Report 2 (Grind Collective 99.92%, Honeycomb Larder 96.93%, The Pencil Case 781.56%). Before I rank "biggest cost, no lift" discounts for Marco, I need to know whether this is a real zero-margin giveaway or a billing-model artifact where the actual revenue is collected via subscription invoices rather than the order itself. Getting this wrong would make me tell Marco to kill a discount that isn't actually losing money, or miss one that genuinely is.
(2) Report 3's abuse framing was broken: usage_limit and per_customer_limit were NULL for every coupon shown, so "max redemptions by a customer > limit" could never actually fire — we only surfaced raw repeat-redemption counts, not real breaches. I want to redo this narrowly on coupons that actually have a configured cap, which is the only place "abuse" is well-defined.
I'm also starting the hard incrementality question (Marco/Tobias Q2) now rather than waiting, using a within-customer before/after comparison (discounted order value vs. the same customers' other, non-discounted orders) as an honest, approximate read — this needs iteration so it's better to see a first pass early.
All three tonight are independent and don't block each other.
The engineer · 1 dry run on the empty schema, then the submission
WITH redemptions AS ( SELECT cr.coupon_id, cr.user_id, cr.discount_amount, cr.currency_code, cr.redeemed_at FROM coupon_redemptions cr WHERE cr.redeemed_at >= DATE '2023-01-01' AND cr.redeemed_at < DATE '2026-01-01' ), coupon_stats AS ( SELECT r.coupon_id, COUNT(*) AS times_redeemed, COUNT(DISTINCT r.user_id) AS distinct_customers, SUM(r.discount_amount / COALESCE(er.rate, 1)) AS total_discount_eur FROM redemptions r LEFT JOIN exchange_rates er ON er.base_code = 'EUR' AND er.quote_code = r.currency_code AND er.as_of = CAST(r.redeemed_at AS date) GROUP BY r.coupon_id ), per_customer AS ( SELECT r.coupon_id, r.user_id, COUNT(*) AS redemption_count FROM redemptions r GROUP BY r.coupon_id, r.user_id ), customer_stats AS ( SELECT pc.coupon_id, MAX(pc.redemption_count) AS max_redemptions_by_customer, COUNT(*) FILTER (WHERE c.per_customer_limit IS NOT NULL AND pc.redemption_count > c.per_customer_limit) AS customers_exceeding FROM per_customer pc JOIN coupons c ON c.id = pc.coupon_id GROUP BY pc.coupon_id ) SELECT c.code AS coupon_code, t.name AS tenant_name, c.status, c.usage_limit, c.per_customer_limit, COALESCE(cs.times_redeemed, 0) AS times_redeemed, CASE WHEN c.usage_limit IS NOT NULL THEN GREATEST(COALESCE(cs.times_redeemed, 0) - c.usage_limit, 0) ELSE 0 END AS redemptions_over_usage_limit, COALESCE(custs.max_redemptions_by_customer, 0) AS max_redemptions_by_customer, COALESCE(custs.customers_exceeding, 0) AS customers_exceeding_per_customer_limit, ROUND(COALESCE(cs.total_discount_eur, 0), 2) AS total_discount_redeemed_eur, COUNT(*) OVER () AS total_matching_coupons FROM coupons c JOIN tenants t ON t.id = c.tenant_id LEFT JOIN coupon_stats cs ON cs.coupon_id = c.id LEFT JOIN customer_stats custs ON custs.coupon_id = c.id WHERE (c.usage_limit IS NOT NULL OR c.per_customer_limit IS NOT NULL) AND ( (c.usage_limit IS NOT NULL AND COALESCE(cs.times_redeemed, 0) > c.usage_limit) OR COALESCE(custs.customers_exceeding, 0) > 0 ) ORDER BY redemptions_over_usage_limit DESC, customers_exceeding_per_customer_limit DESC, coupon_code ASC LIMIT 50
“Query compiles cleanly. Submitting.”
“Submitted. Summary of the approach:
- Grain: one row per coupon, restricted to coupons with a configured usage_limit and/or per_customer_limit, further filtered to only those actually breached (either total redemptions exceed usage_limit, or at least one customer exceeds per_customer_limit).
- Conversion: discount amounts converted to EUR day-by-day using exchange_rates (EUR→currency rate, divided out), based on each redemption's own currency_code/redeemed_at — this made the orders join unnecessary since those fields are already on coupon_redemptions.
- Per-customer logic: a subquery counts redemptions per (coupon, user), then rolls up into max redemptions by a single customer and the count of customers exceeding the per-customer cap.
- Ordering/paging: sorted by redemptions-over-limit desc, then customers-exceeding desc, then coupon code; capped at 50 rows, with a total_matching_coupons column via a window function so the analyst can see if more rows exist beyond the printed page.”
As Oliver Grant saw it, from the small dataset the agents worked on
coupon_code | tenant_name | status | usage_limit | per_customer_limit | times_redeemed | redemptions_over_usage_limit | max_redemptions_by_customer | customers_exceeding_per_customer_limit | total_discount_redeemed_eur | total_matching_coupons ------------+-------------+--------+-------------+--------------------+----------------+------------------------------+-----------------------------+----------------------------------------+-----------------------------+----------------------- (0 rows)
The memo and the queries that followed; links found by title, so inferred
It builds on:
Changed only where the benchmark needs the same result on every system
WITH redemptions AS ( SELECT cr.coupon_id, cr.user_id, cr.discount_amount, cr.currency_code, cr.redeemed_at cr.coupon_id AS coupon_id, cr.user_id AS user_id, cr.discount_amount AS discount_amount, cr.currency_code AS currency_code, cr.redeemed_at AS redeemed_at FROM coupon_redemptions cr WHERE cr.redeemed_at >= DATE '2023-01-01' AND cr.redeemed_at < DATE '2026-01-01'),coupon_stats AS ( SELECT r.coupon_id, r.coupon_id AS coupon_id, COUNT(*) AS times_redeemed, COUNT(DISTINCT r.user_id) AS distinct_customers, SUM(r.discount_amount / COALESCE(er.rate, 1)) AS total_discount_eur SUM(CAST(r.discount_amount / COALESCE(er.rate, 1) AS NUMERIC(18,6))) AS total_discount_eur FROM redemptions r LEFT JOIN exchange_rates er ON er.base_code = 'EUR' AND er.quote_code = r.currency_code AND er.as_of = CAST(r.redeemed_at AS date) GROUP BY r.coupon_id),per_customer AS ( SELECT r.coupon_id, r.user_id, r.coupon_id AS coupon_id, r.user_id AS user_id, COUNT(*) AS redemption_count FROM redemptions r GROUP BY r.coupon_id, r.user_id),customer_stats AS ( SELECT pc.coupon_id, pc.coupon_id AS coupon_id, MAX(pc.redemption_count) AS max_redemptions_by_customer, COUNT(*) FILTER (WHERE c.per_customer_limit IS NOT NULL AND pc.redemption_count > c.per_customer_limit) AS customers_exceeding FROM per_customer pc JOIN coupons c ON c.id = pc.coupon_id GROUP BY pc.coupon_id)SELECT c.code AS coupon_code, t.name AS tenant_name, c.status, c.usage_limit, c.per_customer_limit, c.status AS status, c.usage_limit AS usage_limit, c.per_customer_limit AS per_customer_limit, COALESCE(cs.times_redeemed, 0) AS times_redeemed, CASE WHEN c.usage_limit IS NOT NULL THEN GREATEST(COALESCE(cs.times_redeemed, 0) - c.usage_limit, 0) ELSE 0 END AS redemptions_over_usage_limit, COALESCE(custs.max_redemptions_by_customer, 0) AS max_redemptions_by_customer, COALESCE(custs.customers_exceeding, 0) AS customers_exceeding_per_customer_limit, ROUND(COALESCE(cs.total_discount_eur, 0), 2) AS total_discount_redeemed_eur, COALESCE(cs.total_discount_eur, 0) AS total_discount_redeemed_eur, COUNT(*) OVER () AS total_matching_couponsFROM coupons cJOIN tenants t ON t.id = c.tenant_idLEFT JOIN coupon_stats cs ON cs.coupon_id = c.idLEFT JOIN customer_stats custs ON custs.coupon_id = c.idWHERE (c.usage_limit IS NOT NULL OR c.per_customer_limit IS NOT NULL) AND ( (c.usage_limit IS NOT NULL AND COALESCE(cs.times_redeemed, 0) > c.usage_limit) OR COALESCE(custs.customers_exceeding, 0) > 0 )ORDER BY redemptions_over_usage_limit DESC, customers_exceeding_per_customer_limit DESC, coupon_code ASCLIMIT 50ORDER BY redemptions_over_usage_limit DESC NULLS FIRST, customers_exceeding_per_customer_limit DESC NULLS FIRST, coupon_code ASC NULLS LAST, c.id ASC NULLS LAST{{fetch_first(50)}}
WITH redemptions AS ( SELECT cr.coupon_id AS coupon_id, cr.user_id AS user_id, cr.discount_amount AS discount_amount, cr.currency_code AS currency_code, cr.redeemed_at AS redeemed_at FROM coupon_redemptions cr WHERE cr.redeemed_at >= DATE '2023-01-01' AND cr.redeemed_at < DATE '2026-01-01' ), coupon_stats AS ( SELECT r.coupon_id AS coupon_id, COUNT(*) AS times_redeemed, COUNT(DISTINCT r.user_id) AS distinct_customers, SUM(CAST(r.discount_amount / COALESCE(er.rate, 1) AS NUMERIC(18,6))) AS total_discount_eur FROM redemptions r LEFT JOIN exchange_rates er ON er.base_code = 'EUR' AND er.quote_code = r.currency_code AND er.as_of = CAST(r.redeemed_at AS date) GROUP BY r.coupon_id ), per_customer AS ( SELECT r.coupon_id AS coupon_id, r.user_id AS user_id, COUNT(*) AS redemption_count FROM redemptions r GROUP BY r.coupon_id, r.user_id ), customer_stats AS ( SELECT pc.coupon_id AS coupon_id, MAX(pc.redemption_count) AS max_redemptions_by_customer, COUNT(*) FILTER (WHERE c.per_customer_limit IS NOT NULL AND pc.redemption_count > c.per_customer_limit) AS customers_exceeding FROM per_customer pc JOIN coupons c ON c.id = pc.coupon_id GROUP BY pc.coupon_id ) SELECT c.code AS coupon_code, t.name AS tenant_name, c.status AS status, c.usage_limit AS usage_limit, c.per_customer_limit AS per_customer_limit, COALESCE(cs.times_redeemed, 0) AS times_redeemed, CASE WHEN c.usage_limit IS NOT NULL THEN GREATEST(COALESCE(cs.times_redeemed, 0) - c.usage_limit, 0) ELSE 0 END AS redemptions_over_usage_limit, COALESCE(custs.max_redemptions_by_customer, 0) AS max_redemptions_by_customer, COALESCE(custs.customers_exceeding, 0) AS customers_exceeding_per_customer_limit, COALESCE(cs.total_discount_eur, 0) AS total_discount_redeemed_eur, COUNT(*) OVER () AS total_matching_coupons FROM coupons c JOIN tenants t ON t.id = c.tenant_id LEFT JOIN coupon_stats cs ON cs.coupon_id = c.id LEFT JOIN customer_stats custs ON custs.coupon_id = c.id WHERE (c.usage_limit IS NOT NULL OR c.per_customer_limit IS NOT NULL) AND ( (c.usage_limit IS NOT NULL AND COALESCE(cs.times_redeemed, 0) > c.usage_limit) OR COALESCE(custs.customers_exceeding, 0) > 0 ) ORDER BY redemptions_over_usage_limit DESC NULLS FIRST, customers_exceeding_per_customer_limit DESC NULLS FIRST, coupon_code ASC NULLS LAST, c.id ASC NULLS LAST FETCH FIRST 50 ROWS ONLY
WITH redemptions AS ( SELECT cr.coupon_id AS coupon_id, cr.user_id AS user_id, cr.discount_amount AS discount_amount, cr.currency_code AS currency_code, cr.redeemed_at AS redeemed_at FROM coupon_redemptions cr WHERE cr.redeemed_at >= DATE '2023-01-01' AND cr.redeemed_at < DATE '2026-01-01' ), coupon_stats AS ( SELECT r.coupon_id AS coupon_id, COUNT(*) AS times_redeemed, COUNT(DISTINCT r.user_id) AS distinct_customers, SUM(CAST(r.discount_amount / COALESCE(er.rate, 1) AS NUMERIC(18,6))) AS total_discount_eur FROM redemptions r LEFT JOIN exchange_rates er ON er.base_code = 'EUR' AND er.quote_code = r.currency_code AND er.as_of = CAST(r.redeemed_at AS date) GROUP BY r.coupon_id ), per_customer AS ( SELECT r.coupon_id AS coupon_id, r.user_id AS user_id, COUNT(*) AS redemption_count FROM redemptions r GROUP BY r.coupon_id, r.user_id ), customer_stats AS ( SELECT pc.coupon_id AS coupon_id, MAX(pc.redemption_count) AS max_redemptions_by_customer, COUNT(*) FILTER (WHERE c.per_customer_limit IS NOT NULL AND pc.redemption_count > c.per_customer_limit) AS customers_exceeding FROM per_customer pc JOIN coupons c ON c.id = pc.coupon_id GROUP BY pc.coupon_id ) SELECT c.code AS coupon_code, t.name AS tenant_name, c.status AS status, c.usage_limit AS usage_limit, c.per_customer_limit AS per_customer_limit, COALESCE(cs.times_redeemed, 0) AS times_redeemed, CASE WHEN c.usage_limit IS NOT NULL THEN GREATEST(COALESCE(cs.times_redeemed, 0) - c.usage_limit, 0) ELSE 0 END AS redemptions_over_usage_limit, COALESCE(custs.max_redemptions_by_customer, 0) AS max_redemptions_by_customer, COALESCE(custs.customers_exceeding, 0) AS customers_exceeding_per_customer_limit, COALESCE(cs.total_discount_eur, 0) AS total_discount_redeemed_eur, COUNT(*) OVER () AS total_matching_coupons FROM coupons c JOIN tenants t ON t.id = c.tenant_id LEFT JOIN coupon_stats cs ON cs.coupon_id = c.id LEFT JOIN customer_stats custs ON custs.coupon_id = c.id WHERE (c.usage_limit IS NOT NULL OR c.per_customer_limit IS NOT NULL) AND ( (c.usage_limit IS NOT NULL AND COALESCE(cs.times_redeemed, 0) > c.usage_limit) OR COALESCE(custs.customers_exceeding, 0) > 0 ) ORDER BY redemptions_over_usage_limit DESC NULLS FIRST, customers_exceeding_per_customer_limit DESC NULLS FIRST, coupon_code ASC NULLS LAST, c.id ASC NULLS LAST LIMIT 50
The agents' own records, as the role play wrote them; only the personal data of the person who ran it is redacted
Report request from Oliver Grant (analyst for the Head of Pricing and Promotions): Title: Coupons with a configured usage cap: actual breaches of usage_limit or per_customer_limit Question: Among coupons that actually have a usage_limit or per_customer_limit configured, which ones have been redeemed beyond that stated cap? Grain: one row per coupon (coupons.id) Columns: - coupon code - tenant name - status - usage_limit - per_customer_limit - times_redeemed (actual count from coupon_redemptions) - redemptions over usage_limit (times_redeemed - usage_limit, floor 0) - max redemptions by a single customer - distinct customers whose redemptions exceed per_customer_limit - total discount redeemed (EUR) Details: Source: coupons joined to tenants (name) and coupon_redemptions (for actual counts, distinct user_id, per-user redemption counts) and orders (currency_code, placed_at) for EUR conversion via exchange_rates (base_code='EUR', quote_code=currency_code, as_of=redeemed_at date). Filter to coupons where usage_limit IS NOT NULL OR per_customer_limit IS NOT NULL. Use full history (redeemed_at 2023-01-01 to 2025-12-31) since a cap can be breached across the coupon's whole life, not just 2025. Order by 'redemptions over usage_limit' descending, then 'distinct customers whose redemptions exceed per_customer_limit' descending, coupon code ascending as final tie-break. Note total row count; print top 50. Check your query with the warehouse's dry_run tool, then hand it in with submit.
dry_runWITH redemptions AS ( SELECT cr.coupon_id, cr.user_id, cr.discount_amount, cr.currency_code, cr.redeemed_at FROM coupon_redemptions cr WHERE cr.redeemed_at >= DATE '2023-01-01' AND cr.redeemed_at < DATE '2026-01-01' ), coupon_stats AS ( SELECT r.coupon_id, COUNT(*) AS times_redeemed, COUNT(DISTINCT r.user_id) AS distinct_customers, SUM(r.discount_amount / COALESCE(er.rate, 1)) AS total_discount_eur FROM redemptions r LEFT JOIN exchange_rates er ON er.base_code = 'EUR' AND er.quote_code = r.currency_code AND er.as_of = CAST(r.redeemed_at AS date) GROUP BY r.coupon_id ), per_customer AS ( SELECT r.coupon_id, r.user_id, COUNT(*) AS redemption_count FROM redemptions r GROUP BY r.coupon_id, r.user_id ), customer_stats AS ( SELECT pc.coupon_id, MAX(pc.redemption_count) AS max_redemptions_by_customer, COUNT(*) FILTER (WHERE c.per_customer_limit IS NOT NULL AND pc.redemption_count > c.per_customer_limit) AS customers_exceeding FROM per_customer pc JOIN coupons c ON c.id = pc.coupon_id GROUP BY pc.coupon_id ) SELECT c.code AS coupon_code, t.name AS tenant_name, c.status, c.usage_limit, c.per_customer_limit, COALESCE(cs.times_redeemed, 0) AS times_redeemed, CASE WHEN c.usage_limit IS NOT NULL THEN GREATEST(COALESCE(cs.times_redeemed, 0) - c.usage_limit, 0) ELSE 0 END AS redemptions_over_usage_limit, COALESCE(custs.max_redemptions_by_customer, 0) AS max_redemptions_by_customer, COALESCE(custs.customers_exceeding, 0) AS customers_exceeding_per_customer_limit, ROUND(COALESCE(cs.total_discount_eur, 0), 2) AS total_discount_redeemed_eur, COUNT(*) OVER () AS total_matching_coupons FROM coupons c JOIN tenants t ON t.id = c.tenant_id LEFT JOIN coupon_stats cs ON cs.coupon_id = c.id LEFT JOIN customer_stats custs ON custs.coupon_id = c.id WHERE (c.usage_limit IS NOT NULL OR c.per_customer_limit IS NOT NULL) AND ( (c.usage_limit IS NOT NULL AND COALESCE(cs.times_redeemed, 0) > c.usage_limit) OR COALESCE(custs.customers_exceeding, 0) > 0 ) ORDER BY redemptions_over_usage_limit DESC, customers_exceeding_per_customer_limit DESC, coupon_code ASC LIMIT 50
STATUS: COMPILES (dry run on the empty schema, no data read) COLUMNS: coupon_code, tenant_name, status, usage_limit, per_customer_limit, times_redeemed, redemptions_over_usage_limit, max_redemptions_by_customer, customers_exceeding_per_customer_limit, total_discount_redeemed_eur, total_matching_coupons
submitWITH redemptions AS ( SELECT cr.coupon_id, cr.user_id, cr.discount_amount, cr.currency_code, cr.redeemed_at FROM coupon_redemptions cr WHERE cr.redeemed_at >= DATE '2023-01-01' AND cr.redeemed_at < DATE '2026-01-01' ), coupon_stats AS ( SELECT r.coupon_id, COUNT(*) AS times_redeemed, COUNT(DISTINCT r.user_id) AS distinct_customers, SUM(r.discount_amount / COALESCE(er.rate, 1)) AS total_discount_eur FROM redemptions r LEFT JOIN exchange_rates er ON er.base_code = 'EUR' AND er.quote_code = r.currency_code AND er.as_of = CAST(r.redeemed_at AS date) GROUP BY r.coupon_id ), per_customer AS ( SELECT r.coupon_id, r.user_id, COUNT(*) AS redemption_count FROM redemptions r GROUP BY r.coupon_id, r.user_id ), customer_stats AS ( SELECT pc.coupon_id, MAX(pc.redemption_count) AS max_redemptions_by_customer, COUNT(*) FILTER (WHERE c.per_customer_limit IS NOT NULL AND pc.redemption_count > c.per_customer_limit) AS customers_exceeding FROM per_customer pc JOIN coupons c ON c.id = pc.coupon_id GROUP BY pc.coupon_id ) SELECT c.code AS coupon_code, t.name AS tenant_name, c.status, c.usage_limit, c.per_customer_limit, COALESCE(cs.times_redeemed, 0) AS times_redeemed, CASE WHEN c.usage_limit IS NOT NULL THEN GREATEST(COALESCE(cs.times_redeemed, 0) - c.usage_limit, 0) ELSE 0 END AS redemptions_over_usage_limit, COALESCE(custs.max_redemptions_by_customer, 0) AS max_redemptions_by_customer, COALESCE(custs.customers_exceeding, 0) AS customers_exceeding_per_customer_limit, ROUND(COALESCE(cs.total_discount_eur, 0), 2) AS total_discount_redeemed_eur, COUNT(*) OVER () AS total_matching_coupons FROM coupons c JOIN tenants t ON t.id = c.tenant_id LEFT JOIN coupon_stats cs ON cs.coupon_id = c.id LEFT JOIN customer_stats custs ON custs.coupon_id = c.id WHERE (c.usage_limit IS NOT NULL OR c.per_customer_limit IS NOT NULL) AND ( (c.usage_limit IS NOT NULL AND COALESCE(cs.times_redeemed, 0) > c.usage_limit) OR COALESCE(custs.customers_exceeding, 0) > 0 ) ORDER BY redemptions_over_usage_limit DESC, customers_exceeding_per_customer_limit DESC, coupon_code ASC LIMIT 50
Submitted to tonight's batch. Your work on this request is done.