Queries · q064 · Head of Merchant Success · week 1, night 4
“Which merchants show warning signs right now: rising refunds or cancellations, unpaid invoices, or falling shopper activity?”
Fictional people at a fictional company, each played by a language-model agent. Who they are and what they are told
The manager, at the start of week 1
Subject: What I need for merchant QBRs this month
Hi Arjun,
I'm diving into merchant health this week ahead of January's quarterly business reviews with our biggest accounts. I know you've only got a handful of report slots a night, so here's what matters most to me, roughly in priority order:
For context: these go straight into prep notes for one-on-one merchant reviews, so I care most about being able to point to specific merchants by name and tell a clear story about each one's trajectory. Broad trends across all 120 merchants are useful background, but the top merchants are what I'll be sitting across the table from this month.
Let me know if you want me to rank these differently given the slot constraints — happy to cut the list if needed.
Thanks, Samuel
The analyst · week 1, night 4, request 2 of 3
Trimming detail length after earlier submission issues; same 3 reports as planned, worded more concisely to stay within limits.
The engineer · 1 dry run on the empty schema, then the submission
SELECT t.name AS merchant_name, t.industry, round(coalesce(rr.refund_rate_last, 0) * 100, 2) AS refund_rate_last_90d_pct, round(coalesce(rr.refund_rate_prior, 0) * 100, 2) AS refund_rate_prior_90d_pct, round(coalesce(cr.cancel_rate_last, 0) * 100, 2) AS cancellation_rate_last_90d_pct, round(coalesce(cr.cancel_rate_prior, 0) * 100, 2) AS cancellation_rate_prior_90d_pct, round(coalesce(ov.overdue_eur, 0), 2) AS overdue_invoice_amount_eur, coalesce(ws.sessions_last, 0) AS web_sessions_last_90d, coalesce(ws.sessions_prior, 0) AS web_sessions_prior_90d, round( CASE WHEN coalesce(ws.sessions_prior, 0) = 0 THEN NULL ELSE (ws.sessions_last - ws.sessions_prior) * 100.0 / ws.sessions_prior END, 2 ) AS session_growth_pct FROM tenants t LEFT JOIN ( SELECT ra.tenant_id, ra.refund_last_eur / NULLIF(ca.captured_last_eur, 0) AS refund_rate_last, ra.refund_prior_eur / NULLIF(ca.captured_prior_eur, 0) AS refund_rate_prior FROM ( SELECT tenant_id, SUM(CASE WHEN processed_at >= DATE '2025-10-03' AND processed_at < DATE '2026-01-01' THEN amount_eur ELSE 0 END) AS refund_last_eur, SUM(CASE WHEN processed_at >= DATE '2025-07-05' AND processed_at < DATE '2025-10-03' THEN amount_eur ELSE 0 END) AS refund_prior_eur FROM ( SELECT pr.tenant_id, pr.processed_at, pr.amount / COALESCE(er.rate, 1) AS amount_eur FROM payment_refunds pr LEFT JOIN exchange_rates er ON er.base_code = 'EUR' AND er.quote_code = pr.currency_code AND er.as_of = CAST(pr.processed_at AS date) WHERE pr.status = 'succeeded' AND pr.processed_at >= DATE '2025-07-05' AND pr.processed_at < DATE '2026-01-01' ) ra_inner GROUP BY tenant_id ) ra JOIN ( SELECT tenant_id, SUM(CASE WHEN captured_at >= DATE '2025-10-03' AND captured_at < DATE '2026-01-01' THEN amount_eur ELSE 0 END) AS captured_last_eur, SUM(CASE WHEN captured_at >= DATE '2025-07-05' AND captured_at < DATE '2025-10-03' THEN amount_eur ELSE 0 END) AS captured_prior_eur FROM ( SELECT p.tenant_id, p.captured_at, p.amount / COALESCE(er.rate, 1) AS amount_eur FROM payments p LEFT JOIN exchange_rates er ON er.base_code = 'EUR' AND er.quote_code = p.currency_code AND er.as_of = CAST(p.captured_at AS date) WHERE p.status = 'captured' AND p.captured_at >= DATE '2025-07-05' AND p.captured_at < DATE '2026-01-01' ) ca_inner GROUP BY tenant_id ) ca ON ca.tenant_id = ra.tenant_id ) rr ON rr.tenant_id = t.id LEFT JOIN ( SELECT tenant_id, SUM(CASE WHEN placed_at >= DATE '2025-10-03' AND placed_at < DATE '2026-01-01' AND status = 'cancelled' THEN 1 ELSE 0 END)::decimal / NULLIF(SUM(CASE WHEN placed_at >= DATE '2025-10-03' AND placed_at < DATE '2026-01-01' THEN 1 ELSE 0 END), 0) AS cancel_rate_last, SUM(CASE WHEN placed_at >= DATE '2025-07-05' AND placed_at < DATE '2025-10-03' AND status = 'cancelled' THEN 1 ELSE 0 END)::decimal / NULLIF(SUM(CASE WHEN placed_at >= DATE '2025-07-05' AND placed_at < DATE '2025-10-03' THEN 1 ELSE 0 END), 0) AS cancel_rate_prior FROM orders WHERE placed_at >= DATE '2025-07-05' AND placed_at < DATE '2026-01-01' GROUP BY tenant_id ) cr ON cr.tenant_id = t.id LEFT JOIN ( SELECT i.tenant_id, SUM(i.amount_due / COALESCE(er.rate, 1)) AS overdue_eur FROM invoices i LEFT JOIN exchange_rates er ON er.base_code = 'EUR' AND er.quote_code = i.currency_code AND er.as_of = ( SELECT MAX(er2.as_of) FROM exchange_rates er2 WHERE er2.base_code = 'EUR' AND er2.quote_code = i.currency_code AND er2.as_of <= DATE '2026-01-05' ) WHERE i.status = 'past_due' OR (i.status = 'open' AND i.due_at < DATE '2026-01-05') GROUP BY i.tenant_id ) ov ON ov.tenant_id = t.id LEFT JOIN ( SELECT tenant_id, SUM(CASE WHEN started_at >= DATE '2025-10-03' AND started_at < DATE '2026-01-01' THEN 1 ELSE 0 END) AS sessions_last, SUM(CASE WHEN started_at >= DATE '2025-07-05' AND started_at < DATE '2025-10-03' THEN 1 ELSE 0 END) AS sessions_prior FROM web_sessions WHERE started_at >= DATE '2025-07-05' AND started_at < DATE '2026-01-01' GROUP BY tenant_id ) ws ON ws.tenant_id = t.id ORDER BY overdue_invoice_amount_eur DESC, refund_rate_last_90d_pct DESC, t.id LIMIT 50
“Query compiles and produces the requested columns. Submitting.”
“Submitted. The report joins five period-scoped subqueries (refunds, captured payments, order cancellations, overdue invoices, web sessions) back to tenants, converts all money to EUR via same-day exchange_rates, and computes the requested rates and growth percentage, ordered by overdue EUR descending.”
As Arjun Patel saw it, from the small dataset the agents worked on
merchant_name | industry | refund_rate_last_90d_pct | refund_rate_prior_90d_pct | cancellation_rate_last_90d_pct | cancellation_rate_prior_90d_pct | overdue_invoice_amount_eur | web_sessions_last_90d | web_sessions_prior_90d | session_growth_pct ------------------------------+---------------------------+--------------------------+---------------------------+--------------------------------+---------------------------------+----------------------------+-----------------------+------------------------+------------------- Kontor24 Bürobedarf | Office Supplies (B2B) | 0.33 | 0.0 | 2.6 | 1.79 | 64191.09 | 58 | 63 | -7.94 Castell Fasteners | Industrial Supplies (B2B) | 0.88 | 0.0 | 0.0 | 2.7 | 5079.8 | 40 | 72 | -44.44 OfficeHub Nordic | Office Supplies (B2B) | 0.0 | 26.56 | 0.0 | 4.65 | 4767.95 | 67 | 59 | 13.56 Ballycorran Industrial Supply | Industrial Supplies (B2B) | 11.09 | 0.12 | 1.14 | 1.28 | 3346.98 | 80 | 96 | -16.67 Midland Safety Wear | Industrial Supplies (B2B) | 5.4 | 9.48 | 5.13 | 2.08 | 2348.21 | 39 | 32 | 21.88 Deskline Supplies | Office Supplies (B2B) | 0.0 | 0.0 | 0.0 | 0.0 | 399.32 | 14 | 11 | 27.27 Polder Packaging | Industrial Supplies (B2B) | 13.7 | 0.0 | 0.0 | 0.0 | 169.46 | 25 | 13 | 92.31 Brennquell Kaffee | Food & Coffee | 0.9 | 0.91 | 2.08 | 0.83 | 41.84 | 666 | 494 | 34.82 Brick & Bobbin | Apparel & Footwear | 291.17 | 26.86 | 0.0 | 0.0 | 0.0 | 33 | 18 | 83.33 Kiezkind | Apparel & Footwear | 159.75 | 0.0 | 0.0 | 0.0 | 0.0 | 25 | 13 | 92.31 Trailmark | Sports & Outdoor | 157.98 | 35.45 | 0.0 | 14.29 | 0.0 | 10 | 20 | -50.0 Bytefield | Consumer Electronics | 134.47 | 0.0 | 8.33 | 0.0 | 0.0 | 26 | 15 | 73.33 Little Larch Kids | Apparel & Footwear | 94.74 | 15.06 | 22.22 | 0.0 | 0.0 | 19 | 8 | 137.5 Fell & Fjell | Sports & Outdoor | 89.11 | 4.47 | 5.56 | 9.09 | 0.0 | 53 | 60 | -11.67 Ondine Botanicals | Beauty | 61.07 | 5.23 | 0.0 | 14.29 | 0.0 | 23 | 11 | 109.09 Northstar Watches | Jewelry & Accessories | 53.24 | 0.0 | 20.0 | 0.0 | 0.0 | 30 | 18 | 66.67 Fjordline Wear | Apparel & Footwear | 42.26 | 54.72 | 12.0 | 0.0 | 0.0 | 68 | 27 | 151.85 Lumen Collective | Apparel & Footwear | 40.79 | 35.36 | 4.55 | 0.0 | 0.0 | 36 | 27 | 33.33 Cragsley Outfitters | Apparel & Footwear | 38.34 | 44.45 | 3.93 | 4.59 | 0.0 | 2942 | 1858 | 58.34 Studio Vrij | Apparel & Footwear | 37.28 | 88.42 | 5.93 | 5.66 | 0.0 | 423 | 310 | 36.45 Atelier Nouveau | Apparel & Footwear | 36.65 | 40.59 | 3.13 | 5.88 | 0.0 | 73 | 23 | 217.39 Marrowby & Vane | Apparel & Footwear | 31.77 | 39.47 | 4.57 | 5.08 | 0.0 | 1299 | 826 | 57.26 Lamplight Living | Home & Living | 30.88 | 0.73 | 5.26 | 0.0 | 0.0 | 69 | 35 | 97.14 Copper Lane | Apparel & Footwear | 27.79 | 0.0 | 0.0 | 0.0 | 0.0 | 25 | 2 | 1150.0 Gratlinie Outdoor | Sports & Outdoor | 25.09 | 22.79 | 1.37 | 5.66 | 0.0 | 266 | 169 | 57.4 Cinder Peak Sports Co. | Sports & Outdoor | 24.1 | 10.31 | 2.83 | 5.56 | 0.0 | 264 | 206 | 28.16 Rue Lafayette Studio | Apparel & Footwear | 23.89 | 31.33 | 6.35 | 13.95 | 0.0 | 136 | 78 | 74.36 Velvet Ash | Apparel & Footwear | 23.54 | 53.65 | 3.85 | 3.57 | 0.0 | 78 | 62 | 25.81 Bijoux Lune | Jewelry & Accessories | 23.23 | 0.0 | 0.0 | 0.0 | 0.0 | 18 | 18 | 0.0 Ostwind Mode | Apparel & Footwear | 21.01 | 21.53 | 0.0 | 4.35 | 0.0 | 69 | 65 | 6.15 Thistlecombe | Apparel & Footwear | 20.79 | 29.15 | 4.55 | 8.33 | 0.0 | 133 | 63 | 111.11 Oakhurst Tailoring | Apparel & Footwear | 20.52 | 15.83 | 3.61 | 10.81 | 0.0 | 131 | 81 | 61.73 Willow & Wren | Home & Living | 20.41 | 7.71 | 3.03 | 0.0 | 0.0 | 91 | 60 | 51.67 Velours Paris | Beauty | 20.19 | 0.0 | 0.0 | 0.0 | 0.0 | 21 | 11 | 90.91 Strandgut | Apparel & Footwear | 16.08 | 74.04 | 0.0 | 0.0 | 0.0 | 41 | 21 | 95.24 Lumio Tech | Consumer Electronics | 14.74 | 0.0 | 0.0 | 0.0 | 0.0 | 23 | 5 | 360.0 Sorella Skin | Beauty | 14.62 | 2.41 | 6.67 | 4.17 | 0.0 | 43 | 23 | 86.96 Ampfeld Elektronik | Consumer Electronics | 14.5 | 2.52 | 4.17 | 3.8 | 0.0 | 683 | 292 | 133.9 Ridgeback Gear | Sports & Outdoor | 14.14 | 17.35 | 3.33 | 7.69 | 0.0 | 44 | 39 | 12.82 Hus & Hem | Home & Living | 13.87 | 12.11 | 7.14 | 22.22 | 0.0 | 71 | 26 | 173.08 Saffron & Sage | Beauty | 13.33 | 10.65 | 2.27 | 8.0 | 0.0 | 47 | 31 | 51.61 Noordzee Surfwear | Apparel & Footwear | 11.72 | 26.41 | 0.0 | 12.5 | 0.0 | 67 | 42 | 59.52 Kettle & Key | Home & Living | 11.71 | 0.0 | 0.0 | 0.0 | 0.0 | 47 | 31 | 51.61 Seilschaft | Sports & Outdoor | 11.51 | 0.0 | 22.22 | 0.0 | 0.0 | 35 | 10 | 250.0 Maison Clair | Apparel & Footwear | 11.13 | 12.44 | 7.41 | 0.0 | 0.0 | 44 | 21 | 109.52 Nordic Bloom Cosmetics | Beauty | 10.59 | 15.03 | 10.42 | 10.81 | 0.0 | 74 | 62 | 19.35 Basecamp Nord | Sports & Outdoor | 10.29 | 5.57 | 10.0 | 0.0 | 0.0 | 24 | 13 | 84.62 Wiesgrund Wohnen | Home & Living | 10.13 | 11.57 | 2.7 | 3.28 | 0.0 | 223 | 159 | 40.25 Feather & Fin | Pet Supplies | 9.93 | 4.61 | 3.95 | 2.0 | 0.0 | 58 | 47 | 23.4 Petalcourt Beauty | Beauty | 9.38 | 13.98 | 5.16 | 4.32 | 0.0 | 481 | 216 | 122.69 (50 rows)
The memo and the queries that followed; links found by title, so inferred
Later queries that build on this report:
It builds on:
Changed only where the benchmark needs the same result on every system
SELECT t.name AS merchant_name, t.industry, round(coalesce(rr.refund_rate_last, 0) * 100, 2) AS refund_rate_last_90d_pct, round(coalesce(rr.refund_rate_prior, 0) * 100, 2) AS refund_rate_prior_90d_pct, round(coalesce(cr.cancel_rate_last, 0) * 100, 2) AS cancellation_rate_last_90d_pct, round(coalesce(cr.cancel_rate_prior, 0) * 100, 2) AS cancellation_rate_prior_90d_pct, round(coalesce(ov.overdue_eur, 0), 2) AS overdue_invoice_amount_eur, t.industry AS industry, coalesce(rr.refund_rate_last, 0) * 100 AS refund_rate_last_90d_pct, coalesce(rr.refund_rate_prior, 0) * 100 AS refund_rate_prior_90d_pct, coalesce(cr.cancel_rate_last, 0) * 100 AS cancellation_rate_last_90d_pct, coalesce(cr.cancel_rate_prior, 0) * 100 AS cancellation_rate_prior_90d_pct, coalesce(ov.overdue_eur, 0) AS overdue_invoice_amount_eur, coalesce(ws.sessions_last, 0) AS web_sessions_last_90d, coalesce(ws.sessions_prior, 0) AS web_sessions_prior_90d, round( CASE WHEN coalesce(ws.sessions_prior, 0) = 0 THEN NULL ELSE (ws.sessions_last - ws.sessions_prior) * 100.0 / ws.sessions_prior END, 2 ) AS session_growth_pct CASE WHEN coalesce(ws.sessions_prior, 0) = 0 THEN NULL ELSE (ws.sessions_last - ws.sessions_prior) * 100.0 / ws.sessions_prior END AS session_growth_pctFROM tenants tLEFT JOIN ( SELECT ra.tenant_id, SELECT ra.tenant_id AS tenant_id, ra.refund_last_eur / NULLIF(ca.captured_last_eur, 0) AS refund_rate_last, ra.refund_prior_eur / NULLIF(ca.captured_prior_eur, 0) AS refund_rate_prior FROM ( SELECT tenant_id, SUM(CASE WHEN processed_at >= DATE '2025-10-03' AND processed_at < DATE '2026-01-01' THEN amount_eur ELSE 0 END) AS refund_last_eur, SUM(CASE WHEN processed_at >= DATE '2025-07-05' AND processed_at < DATE '2025-10-03' THEN amount_eur ELSE 0 END) AS refund_prior_eur FROM ( SELECT pr.tenant_id, pr.processed_at, pr.amount / COALESCE(er.rate, 1) AS amount_eur SELECT pr.tenant_id AS tenant_id, pr.processed_at AS processed_at, CAST(pr.amount / COALESCE(er.rate, 1) AS NUMERIC(18,6)) AS amount_eur FROM payment_refunds pr LEFT JOIN exchange_rates er ON er.base_code = 'EUR' AND er.quote_code = pr.currency_code AND er.as_of = CAST(pr.processed_at AS date) WHERE pr.status = 'succeeded' AND pr.processed_at >= DATE '2025-07-05' AND pr.processed_at < DATE '2026-01-01' ) ra_inner GROUP BY tenant_id ) ra JOIN ( SELECT tenant_id, SUM(CASE WHEN captured_at >= DATE '2025-10-03' AND captured_at < DATE '2026-01-01' THEN amount_eur ELSE 0 END) AS captured_last_eur, SUM(CASE WHEN captured_at >= DATE '2025-07-05' AND captured_at < DATE '2025-10-03' THEN amount_eur ELSE 0 END) AS captured_prior_eur FROM ( SELECT p.tenant_id, p.captured_at, p.amount / COALESCE(er.rate, 1) AS amount_eur SELECT p.tenant_id AS tenant_id, p.captured_at AS captured_at, CAST(p.amount / COALESCE(er.rate, 1) AS NUMERIC(18,6)) AS amount_eur FROM payments p LEFT JOIN exchange_rates er ON er.base_code = 'EUR' AND er.quote_code = p.currency_code AND er.as_of = CAST(p.captured_at AS date) WHERE p.status = 'captured' AND p.captured_at >= DATE '2025-07-05' AND p.captured_at < DATE '2026-01-01' ) ca_inner GROUP BY tenant_id ) ca ON ca.tenant_id = ra.tenant_id) rr ON rr.tenant_id = t.idLEFT JOIN ( SELECT tenant_id, SUM(CASE WHEN placed_at >= DATE '2025-10-03' AND placed_at < DATE '2026-01-01' AND status = 'cancelled' THEN 1 ELSE 0 END)::decimal CAST(SUM(CASE WHEN placed_at >= DATE '2025-10-03' AND placed_at < DATE '2026-01-01' AND status = 'cancelled' THEN 1 ELSE 0 END) AS decimal(18,6)) / NULLIF(SUM(CASE WHEN placed_at >= DATE '2025-10-03' AND placed_at < DATE '2026-01-01' THEN 1 ELSE 0 END), 0) AS cancel_rate_last, SUM(CASE WHEN placed_at >= DATE '2025-07-05' AND placed_at < DATE '2025-10-03' AND status = 'cancelled' THEN 1 ELSE 0 END)::decimal CAST(SUM(CASE WHEN placed_at >= DATE '2025-07-05' AND placed_at < DATE '2025-10-03' AND status = 'cancelled' THEN 1 ELSE 0 END) AS decimal(18,6)) / NULLIF(SUM(CASE WHEN placed_at >= DATE '2025-07-05' AND placed_at < DATE '2025-10-03' THEN 1 ELSE 0 END), 0) AS cancel_rate_prior FROM orders WHERE placed_at >= DATE '2025-07-05' AND placed_at < DATE '2026-01-01' GROUP BY tenant_id) cr ON cr.tenant_id = t.idLEFT JOIN ( SELECT i.tenant_id, SUM(i.amount_due / COALESCE(er.rate, 1)) AS overdue_eur SELECT i.tenant_id AS tenant_id, SUM(CAST(i.amount_due / COALESCE(er.rate, 1) AS NUMERIC(18,6))) AS overdue_eur FROM invoices i LEFT JOIN exchange_rates er ON er.base_code = 'EUR' AND er.quote_code = i.currency_code AND er.as_of = ( SELECT MAX(er2.as_of) FROM exchange_rates er2 WHERE er2.base_code = 'EUR' AND er2.quote_code = i.currency_code AND er2.as_of <= DATE '2026-01-05' ) WHERE i.status = 'past_due' OR (i.status = 'open' AND i.due_at < DATE '2026-01-05') GROUP BY i.tenant_id) ov ON ov.tenant_id = t.idLEFT JOIN ( SELECT tenant_id, SUM(CASE WHEN started_at >= DATE '2025-10-03' AND started_at < DATE '2026-01-01' THEN 1 ELSE 0 END) AS sessions_last, SUM(CASE WHEN started_at >= DATE '2025-07-05' AND started_at < DATE '2025-10-03' THEN 1 ELSE 0 END) AS sessions_prior FROM web_sessions WHERE started_at >= DATE '2025-07-05' AND started_at < DATE '2026-01-01' GROUP BY tenant_id) ws ON ws.tenant_id = t.idORDER BY overdue_invoice_amount_eur DESC, refund_rate_last_90d_pct DESC, t.idLIMIT 50ORDER BY overdue_invoice_amount_eur DESC NULLS FIRST, refund_rate_last_90d_pct DESC NULLS FIRST, t.id NULLS LAST{{fetch_first(50)}}
SELECT t.name AS merchant_name, t.industry AS industry, coalesce(rr.refund_rate_last, 0) * 100 AS refund_rate_last_90d_pct, coalesce(rr.refund_rate_prior, 0) * 100 AS refund_rate_prior_90d_pct, coalesce(cr.cancel_rate_last, 0) * 100 AS cancellation_rate_last_90d_pct, coalesce(cr.cancel_rate_prior, 0) * 100 AS cancellation_rate_prior_90d_pct, coalesce(ov.overdue_eur, 0) AS overdue_invoice_amount_eur, coalesce(ws.sessions_last, 0) AS web_sessions_last_90d, coalesce(ws.sessions_prior, 0) AS web_sessions_prior_90d, CASE WHEN coalesce(ws.sessions_prior, 0) = 0 THEN NULL ELSE (ws.sessions_last - ws.sessions_prior) * 100.0 / ws.sessions_prior END AS session_growth_pct FROM tenants t LEFT JOIN ( SELECT ra.tenant_id AS tenant_id, ra.refund_last_eur / NULLIF(ca.captured_last_eur, 0) AS refund_rate_last, ra.refund_prior_eur / NULLIF(ca.captured_prior_eur, 0) AS refund_rate_prior FROM ( SELECT tenant_id, SUM(CASE WHEN processed_at >= DATE '2025-10-03' AND processed_at < DATE '2026-01-01' THEN amount_eur ELSE 0 END) AS refund_last_eur, SUM(CASE WHEN processed_at >= DATE '2025-07-05' AND processed_at < DATE '2025-10-03' THEN amount_eur ELSE 0 END) AS refund_prior_eur FROM ( SELECT pr.tenant_id AS tenant_id, pr.processed_at AS processed_at, CAST(pr.amount / COALESCE(er.rate, 1) AS NUMERIC(18,6)) AS amount_eur FROM payment_refunds pr LEFT JOIN exchange_rates er ON er.base_code = 'EUR' AND er.quote_code = pr.currency_code AND er.as_of = CAST(pr.processed_at AS date) WHERE pr.status = 'succeeded' AND pr.processed_at >= DATE '2025-07-05' AND pr.processed_at < DATE '2026-01-01' ) ra_inner GROUP BY tenant_id ) ra JOIN ( SELECT tenant_id, SUM(CASE WHEN captured_at >= DATE '2025-10-03' AND captured_at < DATE '2026-01-01' THEN amount_eur ELSE 0 END) AS captured_last_eur, SUM(CASE WHEN captured_at >= DATE '2025-07-05' AND captured_at < DATE '2025-10-03' THEN amount_eur ELSE 0 END) AS captured_prior_eur FROM ( SELECT p.tenant_id AS tenant_id, p.captured_at AS captured_at, CAST(p.amount / COALESCE(er.rate, 1) AS NUMERIC(18,6)) AS amount_eur FROM payments p LEFT JOIN exchange_rates er ON er.base_code = 'EUR' AND er.quote_code = p.currency_code AND er.as_of = CAST(p.captured_at AS date) WHERE p.status = 'captured' AND p.captured_at >= DATE '2025-07-05' AND p.captured_at < DATE '2026-01-01' ) ca_inner GROUP BY tenant_id ) ca ON ca.tenant_id = ra.tenant_id ) rr ON rr.tenant_id = t.id LEFT JOIN ( SELECT tenant_id, CAST(SUM(CASE WHEN placed_at >= DATE '2025-10-03' AND placed_at < DATE '2026-01-01' AND status = 'cancelled' THEN 1 ELSE 0 END) AS decimal(18,6)) / NULLIF(SUM(CASE WHEN placed_at >= DATE '2025-10-03' AND placed_at < DATE '2026-01-01' THEN 1 ELSE 0 END), 0) AS cancel_rate_last, CAST(SUM(CASE WHEN placed_at >= DATE '2025-07-05' AND placed_at < DATE '2025-10-03' AND status = 'cancelled' THEN 1 ELSE 0 END) AS decimal(18,6)) / NULLIF(SUM(CASE WHEN placed_at >= DATE '2025-07-05' AND placed_at < DATE '2025-10-03' THEN 1 ELSE 0 END), 0) AS cancel_rate_prior FROM orders WHERE placed_at >= DATE '2025-07-05' AND placed_at < DATE '2026-01-01' GROUP BY tenant_id ) cr ON cr.tenant_id = t.id LEFT JOIN ( SELECT i.tenant_id AS tenant_id, SUM(CAST(i.amount_due / COALESCE(er.rate, 1) AS NUMERIC(18,6))) AS overdue_eur FROM invoices i LEFT JOIN exchange_rates er ON er.base_code = 'EUR' AND er.quote_code = i.currency_code AND er.as_of = ( SELECT MAX(er2.as_of) FROM exchange_rates er2 WHERE er2.base_code = 'EUR' AND er2.quote_code = i.currency_code AND er2.as_of <= DATE '2026-01-05' ) WHERE i.status = 'past_due' OR (i.status = 'open' AND i.due_at < DATE '2026-01-05') GROUP BY i.tenant_id ) ov ON ov.tenant_id = t.id LEFT JOIN ( SELECT tenant_id, SUM(CASE WHEN started_at >= DATE '2025-10-03' AND started_at < DATE '2026-01-01' THEN 1 ELSE 0 END) AS sessions_last, SUM(CASE WHEN started_at >= DATE '2025-07-05' AND started_at < DATE '2025-10-03' THEN 1 ELSE 0 END) AS sessions_prior FROM web_sessions WHERE started_at >= DATE '2025-07-05' AND started_at < DATE '2026-01-01' GROUP BY tenant_id ) ws ON ws.tenant_id = t.id ORDER BY overdue_invoice_amount_eur DESC NULLS FIRST, refund_rate_last_90d_pct DESC NULLS FIRST, t.id NULLS LAST FETCH FIRST 50 ROWS ONLY
SELECT t.name AS merchant_name, t.industry AS industry, coalesce(rr.refund_rate_last, 0) * 100 AS refund_rate_last_90d_pct, coalesce(rr.refund_rate_prior, 0) * 100 AS refund_rate_prior_90d_pct, coalesce(cr.cancel_rate_last, 0) * 100 AS cancellation_rate_last_90d_pct, coalesce(cr.cancel_rate_prior, 0) * 100 AS cancellation_rate_prior_90d_pct, coalesce(ov.overdue_eur, 0) AS overdue_invoice_amount_eur, coalesce(ws.sessions_last, 0) AS web_sessions_last_90d, coalesce(ws.sessions_prior, 0) AS web_sessions_prior_90d, CASE WHEN coalesce(ws.sessions_prior, 0) = 0 THEN NULL ELSE (ws.sessions_last - ws.sessions_prior) * 100.0 / ws.sessions_prior END AS session_growth_pct FROM tenants t LEFT JOIN ( SELECT ra.tenant_id AS tenant_id, ra.refund_last_eur / NULLIF(ca.captured_last_eur, 0) AS refund_rate_last, ra.refund_prior_eur / NULLIF(ca.captured_prior_eur, 0) AS refund_rate_prior FROM ( SELECT tenant_id, SUM(CASE WHEN processed_at >= DATE '2025-10-03' AND processed_at < DATE '2026-01-01' THEN amount_eur ELSE 0 END) AS refund_last_eur, SUM(CASE WHEN processed_at >= DATE '2025-07-05' AND processed_at < DATE '2025-10-03' THEN amount_eur ELSE 0 END) AS refund_prior_eur FROM ( SELECT pr.tenant_id AS tenant_id, pr.processed_at AS processed_at, CAST(pr.amount / COALESCE(er.rate, 1) AS NUMERIC(18,6)) AS amount_eur FROM payment_refunds pr LEFT JOIN exchange_rates er ON er.base_code = 'EUR' AND er.quote_code = pr.currency_code AND er.as_of = CAST(pr.processed_at AS date) WHERE pr.status = 'succeeded' AND pr.processed_at >= DATE '2025-07-05' AND pr.processed_at < DATE '2026-01-01' ) ra_inner GROUP BY tenant_id ) ra JOIN ( SELECT tenant_id, SUM(CASE WHEN captured_at >= DATE '2025-10-03' AND captured_at < DATE '2026-01-01' THEN amount_eur ELSE 0 END) AS captured_last_eur, SUM(CASE WHEN captured_at >= DATE '2025-07-05' AND captured_at < DATE '2025-10-03' THEN amount_eur ELSE 0 END) AS captured_prior_eur FROM ( SELECT p.tenant_id AS tenant_id, p.captured_at AS captured_at, CAST(p.amount / COALESCE(er.rate, 1) AS NUMERIC(18,6)) AS amount_eur FROM payments p LEFT JOIN exchange_rates er ON er.base_code = 'EUR' AND er.quote_code = p.currency_code AND er.as_of = CAST(p.captured_at AS date) WHERE p.status = 'captured' AND p.captured_at >= DATE '2025-07-05' AND p.captured_at < DATE '2026-01-01' ) ca_inner GROUP BY tenant_id ) ca ON ca.tenant_id = ra.tenant_id ) rr ON rr.tenant_id = t.id LEFT JOIN ( SELECT tenant_id, CAST(SUM(CASE WHEN placed_at >= DATE '2025-10-03' AND placed_at < DATE '2026-01-01' AND status = 'cancelled' THEN 1 ELSE 0 END) AS decimal(18,6)) / NULLIF(SUM(CASE WHEN placed_at >= DATE '2025-10-03' AND placed_at < DATE '2026-01-01' THEN 1 ELSE 0 END), 0) AS cancel_rate_last, CAST(SUM(CASE WHEN placed_at >= DATE '2025-07-05' AND placed_at < DATE '2025-10-03' AND status = 'cancelled' THEN 1 ELSE 0 END) AS decimal(18,6)) / NULLIF(SUM(CASE WHEN placed_at >= DATE '2025-07-05' AND placed_at < DATE '2025-10-03' THEN 1 ELSE 0 END), 0) AS cancel_rate_prior FROM orders WHERE placed_at >= DATE '2025-07-05' AND placed_at < DATE '2026-01-01' GROUP BY tenant_id ) cr ON cr.tenant_id = t.id LEFT JOIN ( SELECT i.tenant_id AS tenant_id, SUM(CAST(i.amount_due / COALESCE(er.rate, 1) AS NUMERIC(18,6))) AS overdue_eur FROM invoices i LEFT JOIN exchange_rates er ON er.base_code = 'EUR' AND er.quote_code = i.currency_code AND er.as_of = ( SELECT MAX(er2.as_of) FROM exchange_rates er2 WHERE er2.base_code = 'EUR' AND er2.quote_code = i.currency_code AND er2.as_of <= DATE '2026-01-05' ) WHERE i.status = 'past_due' OR (i.status = 'open' AND i.due_at < DATE '2026-01-05') GROUP BY i.tenant_id ) ov ON ov.tenant_id = t.id LEFT JOIN ( SELECT tenant_id, SUM(CASE WHEN started_at >= DATE '2025-10-03' AND started_at < DATE '2026-01-01' THEN 1 ELSE 0 END) AS sessions_last, SUM(CASE WHEN started_at >= DATE '2025-07-05' AND started_at < DATE '2025-10-03' THEN 1 ELSE 0 END) AS sessions_prior FROM web_sessions WHERE started_at >= DATE '2025-07-05' AND started_at < DATE '2026-01-01' GROUP BY tenant_id ) ws ON ws.tenant_id = t.id ORDER BY overdue_invoice_amount_eur DESC NULLS FIRST, refund_rate_last_90d_pct DESC NULLS FIRST, t.id 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 Arjun Patel (analyst for the Head of Merchant Success): Title: Merchant risk signals: refunds, cancellations, unpaid invoices, shopper drop-off Question: Which merchants show warning signs right now: rising refunds or cancellations, unpaid invoices, or falling shopper activity? Grain: one row per merchant (tenant) Columns: - merchant name - industry - refund rate last 90 days - refund rate prior 90 days - cancellation rate last 90 days - cancellation rate prior 90 days - overdue invoice amount EUR - web sessions last 90 days - web sessions prior 90 days - session growth pct Details: Tables payment_refunds joined to payments for refund rate, equal to refund EUR divided by captured payment EUR per period. Orders for cancellation rate, equal to cancelled orders divided by all orders placed per period. Invoices for overdue amount, equal to amount_due in EUR where status is past_due, or status is open with due date already passed as of 2026-01-05. Web_sessions for session counts per period. Convert money via exchange_rates. Periods: last 90 days is Oct 3 to Dec 31 2025; prior 90 days is Jul 5 to Oct 2 2025. Order by overdue invoice amount EUR descending, tie-break refund rate last 90 days descending, then tenant_id. Cap 50 rows. Check your query with the warehouse's dry_run tool, then hand it in with submit.
dry_runSELECT t.name AS merchant_name, t.industry, round(coalesce(rr.refund_rate_last, 0) * 100, 2) AS refund_rate_last_90d_pct, round(coalesce(rr.refund_rate_prior, 0) * 100, 2) AS refund_rate_prior_90d_pct, round(coalesce(cr.cancel_rate_last, 0) * 100, 2) AS cancellation_rate_last_90d_pct, round(coalesce(cr.cancel_rate_prior, 0) * 100, 2) AS cancellation_rate_prior_90d_pct, round(coalesce(ov.overdue_eur, 0), 2) AS overdue_invoice_amount_eur, coalesce(ws.sessions_last, 0) AS web_sessions_last_90d, coalesce(ws.sessions_prior, 0) AS web_sessions_prior_90d, round( CASE WHEN coalesce(ws.sessions_prior, 0) = 0 THEN NULL ELSE (ws.sessions_last - ws.sessions_prior) * 100.0 / ws.sessions_prior END, 2 ) AS session_growth_pct FROM tenants t LEFT JOIN ( SELECT ra.tenant_id, ra.refund_last_eur / NULLIF(ca.captured_last_eur, 0) AS refund_rate_last, ra.refund_prior_eur / NULLIF(ca.captured_prior_eur, 0) AS refund_rate_prior FROM ( SELECT tenant_id, SUM(CASE WHEN processed_at >= DATE '2025-10-03' AND processed_at < DATE '2026-01-01' THEN amount_eur ELSE 0 END) AS refund_last_eur, SUM(CASE WHEN processed_at >= DATE '2025-07-05' AND processed_at < DATE '2025-10-03' THEN amount_eur ELSE 0 END) AS refund_prior_eur FROM ( SELECT pr.tenant_id, pr.processed_at, pr.amount / COALESCE(er.rate, 1) AS amount_eur FROM payment_refunds pr LEFT JOIN exchange_rates er ON er.base_code = 'EUR' AND er.quote_code = pr.currency_code AND er.as_of = CAST(pr.processed_at AS date) WHERE pr.status = 'succeeded' AND pr.processed_at >= DATE '2025-07-05' AND pr.processed_at < DATE '2026-01-01' ) ra_inner GROUP BY tenant_id ) ra JOIN ( SELECT tenant_id, SUM(CASE WHEN captured_at >= DATE '2025-10-03' AND captured_at < DATE '2026-01-01' THEN amount_eur ELSE 0 END) AS captured_last_eur, SUM(CASE WHEN captured_at >= DATE '2025-07-05' AND captured_at < DATE '2025-10-03' THEN amount_eur ELSE 0 END) AS captured_prior_eur FROM ( SELECT p.tenant_id, p.captured_at, p.amount / COALESCE(er.rate, 1) AS amount_eur FROM payments p LEFT JOIN exchange_rates er ON er.base_code = 'EUR' AND er.quote_code = p.currency_code AND er.as_of = CAST(p.captured_at AS date) WHERE p.status = 'captured' AND p.captured_at >= DATE '2025-07-05' AND p.captured_at < DATE '2026-01-01' ) ca_inner GROUP BY tenant_id ) ca ON ca.tenant_id = ra.tenant_id ) rr ON rr.tenant_id = t.id LEFT JOIN ( SELECT tenant_id, SUM(CASE WHEN placed_at >= DATE '2025-10-03' AND placed_at < DATE '2026-01-01' AND status = 'cancelled' THEN 1 ELSE 0 END)::decimal / NULLIF(SUM(CASE WHEN placed_at >= DATE '2025-10-03' AND placed_at < DATE '2026-01-01' THEN 1 ELSE 0 END), 0) AS cancel_rate_last, SUM(CASE WHEN placed_at >= DATE '2025-07-05' AND placed_at < DATE '2025-10-03' AND status = 'cancelled' THEN 1 ELSE 0 END)::decimal / NULLIF(SUM(CASE WHEN placed_at >= DATE '2025-07-05' AND placed_at < DATE '2025-10-03' THEN 1 ELSE 0 END), 0) AS cancel_rate_prior FROM orders WHERE placed_at >= DATE '2025-07-05' AND placed_at < DATE '2026-01-01' GROUP BY tenant_id ) cr ON cr.tenant_id = t.id LEFT JOIN ( SELECT i.tenant_id, SUM(i.amount_due / COALESCE(er.rate, 1)) AS overdue_eur FROM invoices i LEFT JOIN exchange_rates er ON er.base_code = 'EUR' AND er.quote_code = i.currency_code AND er.as_of = ( SELECT MAX(er2.as_of) FROM exchange_rates er2 WHERE er2.base_code = 'EUR' AND er2.quote_code = i.currency_code AND er2.as_of <= DATE '2026-01-05' ) WHERE i.status = 'past_due' OR (i.status = 'open' AND i.due_at < DATE '2026-01-05') GROUP BY i.tenant_id ) ov ON ov.tenant_id = t.id LEFT JOIN ( SELECT tenant_id, SUM(CASE WHEN started_at >= DATE '2025-10-03' AND started_at < DATE '2026-01-01' THEN 1 ELSE 0 END) AS sessions_last, SUM(CASE WHEN started_at >= DATE '2025-07-05' AND started_at < DATE '2025-10-03' THEN 1 ELSE 0 END) AS sessions_prior FROM web_sessions WHERE started_at >= DATE '2025-07-05' AND started_at < DATE '2026-01-01' GROUP BY tenant_id ) ws ON ws.tenant_id = t.id ORDER BY overdue_invoice_amount_eur DESC, refund_rate_last_90d_pct DESC, t.id LIMIT 50
STATUS: COMPILES (dry run on the empty schema, no data read) COLUMNS: merchant_name, industry, refund_rate_last_90d_pct, refund_rate_prior_90d_pct, cancellation_rate_last_90d_pct, cancellation_rate_prior_90d_pct, overdue_invoice_amount_eur, web_sessions_last_90d, web_sessions_prior_90d, session_growth_pct
submitSELECT t.name AS merchant_name, t.industry, round(coalesce(rr.refund_rate_last, 0) * 100, 2) AS refund_rate_last_90d_pct, round(coalesce(rr.refund_rate_prior, 0) * 100, 2) AS refund_rate_prior_90d_pct, round(coalesce(cr.cancel_rate_last, 0) * 100, 2) AS cancellation_rate_last_90d_pct, round(coalesce(cr.cancel_rate_prior, 0) * 100, 2) AS cancellation_rate_prior_90d_pct, round(coalesce(ov.overdue_eur, 0), 2) AS overdue_invoice_amount_eur, coalesce(ws.sessions_last, 0) AS web_sessions_last_90d, coalesce(ws.sessions_prior, 0) AS web_sessions_prior_90d, round( CASE WHEN coalesce(ws.sessions_prior, 0) = 0 THEN NULL ELSE (ws.sessions_last - ws.sessions_prior) * 100.0 / ws.sessions_prior END, 2 ) AS session_growth_pct FROM tenants t LEFT JOIN ( SELECT ra.tenant_id, ra.refund_last_eur / NULLIF(ca.captured_last_eur, 0) AS refund_rate_last, ra.refund_prior_eur / NULLIF(ca.captured_prior_eur, 0) AS refund_rate_prior FROM ( SELECT tenant_id, SUM(CASE WHEN processed_at >= DATE '2025-10-03' AND processed_at < DATE '2026-01-01' THEN amount_eur ELSE 0 END) AS refund_last_eur, SUM(CASE WHEN processed_at >= DATE '2025-07-05' AND processed_at < DATE '2025-10-03' THEN amount_eur ELSE 0 END) AS refund_prior_eur FROM ( SELECT pr.tenant_id, pr.processed_at, pr.amount / COALESCE(er.rate, 1) AS amount_eur FROM payment_refunds pr LEFT JOIN exchange_rates er ON er.base_code = 'EUR' AND er.quote_code = pr.currency_code AND er.as_of = CAST(pr.processed_at AS date) WHERE pr.status = 'succeeded' AND pr.processed_at >= DATE '2025-07-05' AND pr.processed_at < DATE '2026-01-01' ) ra_inner GROUP BY tenant_id ) ra JOIN ( SELECT tenant_id, SUM(CASE WHEN captured_at >= DATE '2025-10-03' AND captured_at < DATE '2026-01-01' THEN amount_eur ELSE 0 END) AS captured_last_eur, SUM(CASE WHEN captured_at >= DATE '2025-07-05' AND captured_at < DATE '2025-10-03' THEN amount_eur ELSE 0 END) AS captured_prior_eur FROM ( SELECT p.tenant_id, p.captured_at, p.amount / COALESCE(er.rate, 1) AS amount_eur FROM payments p LEFT JOIN exchange_rates er ON er.base_code = 'EUR' AND er.quote_code = p.currency_code AND er.as_of = CAST(p.captured_at AS date) WHERE p.status = 'captured' AND p.captured_at >= DATE '2025-07-05' AND p.captured_at < DATE '2026-01-01' ) ca_inner GROUP BY tenant_id ) ca ON ca.tenant_id = ra.tenant_id ) rr ON rr.tenant_id = t.id LEFT JOIN ( SELECT tenant_id, SUM(CASE WHEN placed_at >= DATE '2025-10-03' AND placed_at < DATE '2026-01-01' AND status = 'cancelled' THEN 1 ELSE 0 END)::decimal / NULLIF(SUM(CASE WHEN placed_at >= DATE '2025-10-03' AND placed_at < DATE '2026-01-01' THEN 1 ELSE 0 END), 0) AS cancel_rate_last, SUM(CASE WHEN placed_at >= DATE '2025-07-05' AND placed_at < DATE '2025-10-03' AND status = 'cancelled' THEN 1 ELSE 0 END)::decimal / NULLIF(SUM(CASE WHEN placed_at >= DATE '2025-07-05' AND placed_at < DATE '2025-10-03' THEN 1 ELSE 0 END), 0) AS cancel_rate_prior FROM orders WHERE placed_at >= DATE '2025-07-05' AND placed_at < DATE '2026-01-01' GROUP BY tenant_id ) cr ON cr.tenant_id = t.id LEFT JOIN ( SELECT i.tenant_id, SUM(i.amount_due / COALESCE(er.rate, 1)) AS overdue_eur FROM invoices i LEFT JOIN exchange_rates er ON er.base_code = 'EUR' AND er.quote_code = i.currency_code AND er.as_of = ( SELECT MAX(er2.as_of) FROM exchange_rates er2 WHERE er2.base_code = 'EUR' AND er2.quote_code = i.currency_code AND er2.as_of <= DATE '2026-01-05' ) WHERE i.status = 'past_due' OR (i.status = 'open' AND i.due_at < DATE '2026-01-05') GROUP BY i.tenant_id ) ov ON ov.tenant_id = t.id LEFT JOIN ( SELECT tenant_id, SUM(CASE WHEN started_at >= DATE '2025-10-03' AND started_at < DATE '2026-01-01' THEN 1 ELSE 0 END) AS sessions_last, SUM(CASE WHEN started_at >= DATE '2025-07-05' AND started_at < DATE '2025-10-03' THEN 1 ELSE 0 END) AS sessions_prior FROM web_sessions WHERE started_at >= DATE '2025-07-05' AND started_at < DATE '2026-01-01' GROUP BY tenant_id ) ws ON ws.tenant_id = t.id ORDER BY overdue_invoice_amount_eur DESC, refund_rate_last_90d_pct DESC, t.id LIMIT 50
Submitted to tonight's batch. Your work on this request is done.