DB Olympics

Queries · q231 · Chief Financial Officer · week 2, night 4

Ledger Reconciliation Outcome by Payment Method, All 2025 Payments

“Is bank_transfer systemically more prone to ledger mismatches as a payment channel, or are the 19 flagged payments a rare exception within a much larger, mostly-clean population?”

Manager · asked the questionTobias LindqvistChief Financial Officer. New this month, previously finance director at a retailer. Preparing the 2025 annual accounts and the 2026 budget.
Analyst · planned the reportKofi MensahHypothesis-driven: states what he expects and designs reports that would prove him wrong.
Engineer · wrote the SQLInesThinks in window functions: ranks, running totals, LAG/LEAD for comparisons, percent-of-total.

Fictional people at a fictional company, each played by a language-model agent. Who they are and what they are told

  1. A business event lands on the Chief Financial Officer's desk

    Week 2

    The external auditors start the 2025 year-end audit in two weeks. They will want to see that the money adds up across the whole chain: what shoppers paid, what was refunded or credited, what merchants received in payouts, what Tidewick kept, and that invoices agree with all of it. They will also trace sample transactions end to end.

  2. Tobias Lindqvist writes to Kofi Mensah

    The manager, at the start of week 2

    Subject: Good progress — but the audit clock is now the priority

    Kofi,

    Thanks — this is useful, and I appreciate you flagging the caveats rather than smoothing them over. A few reactions and then where I want to focus next week.

    What stood out:

    • The correction on the revenue report (off by roughly half, now fixed and cross-checked) is reassuring that you caught it, but it also makes me want a second pair of eyes before anything like this goes near the auditors.
    • The refund numbers disagreeing by 16–40% depending on which source we use is the kind of thing an auditor will ask about directly. I don't want to walk in with two different refund totals and no explanation.
    • Concentration easing as we add merchants is good context for the budget conversation — no urgent follow-up needed there this week.
    • I also saw the notes from pricing and risk this week — the free-delivery giveaway and the refund pattern on that welcome discount are small in isolation, but they're exactly the kind of "where did the money go" questions auditors and I will both ask, so I'd like a rough sense of scale rather than letting them sit as separate anecdotes.

    The big new driver: external audit starts in two weeks. They'll want to walk the full money trail — what a shopper paid, what was refunded or credited back, what the merchant was paid out, what we kept as our fee, and that it all agrees with the invoices and accounts — and they'll pick sample transactions and trace them start to finish. I'd rather we got ahead of that than react to it.

    Questions for this week, in priority order:

    1. Can we demonstrate, for a sample of transactions, that the money actually adds up end to end — shopper payment through refund/credit, payout to the merchant, and our retained fee — so we have something ready to hand the auditors rather than assembling it under time pressure?
    2. Which refund figure should I trust for the 2025 accounts, and why do the two methods disagree? I don't need the full reconciliation solved, but I need to understand the likely cause well enough to explain it credibly if asked.
    3. Where do things stand on getting our own plan-fee revenue into the picture, even approximately, so I'm not presenting half of 2025 revenue as the whole story?
    4. If there's room: roughly how much revenue or margin might be leaking through the control gaps your peers flagged this week (free deliveries to canceled customers, uncapped coupon reuse) — just enough for me to judge whether it's noise or something that belongs in front of the auditors too.

    Audit readiness (#1) is the one I most need — please make that the lead request even if it means FX and B2B receivables slip another week.

    Thanks, Tobias

  3. Kofi Mensah plans the night

    The analyst · week 2, night 4, request 3 of 3

    Report 1 from last night looked alarming at first — ledger net revenue running 13.7-15.9% below payments net amount every quarter — but I think I made the same class of mistake as Night 2: "Sales revenue"/"Shipping income" ledger accounts are booked net of VAT (the VAT portion is credited separately to "VAT / sales tax payable"), while my "payments_net_amount_eur" was the VAT-inclusive gross-minus-refund figure. Spot-checking the Night 2 ledger detail confirms it: Ampfeld Elektronik #1727's VAT credit (2,653.61) is 15.97% of its gross payment (16,619.99) — right in the middle of the quarterly gaps I'm seeing. So this is very likely just tax-inclusive vs tax-exclusive revenue, not money going missing, but I want to prove it precisely before I tell Tobias it's resolved, since "the ledger is €200k short this quarter" is exactly the kind of number an auditor would seize on if I handed it over unexplained.

    Report 1's payment-method breakdown is the one genuine, bounded item left: bank_transfer payments are only 19 of the 249 "other mismatch" payments by count, but carry 40% of the mismatch euros with an average gap of €898 (vs ~€18-33 for card/wallet/credit) — real money, concentrated in a small, nameable list. Report 3 is a clean, reassuring finding: the no-ledger-entries gap was worst in January (2.17%, €1,241) and has fallen to near-zero by October, with only a small December blip plausibly tied to holiday volume — looks like a fixed/fading issue, not an active control failure.

    Tonight (last night before the memo): (1) redo the revenue reconciliation correctly by including VAT in the ledger-side total, to get the real tie-out number; (2) pull the actual 19 bank-transfer mismatched payments as a named, handoff-ready list; (3) check whether bank_transfer payments are systemically more mismatch-prone as a channel (vs. a handful of one-off accidents) by looking at all 2025 bank_transfer payments, not just the flagged ones.

    Ledger Reconciliation Outcome by Payment Method, All 2025 Payments
    Question
    Is bank_transfer systemically more prone to ledger mismatches as a payment channel, or are the 19 flagged payments a rare exception within a much larger, mostly-clean population?
    One row per
    one payment_methods.kind, across ALL 2025 captured payments (not just the mismatched ones)
    Columns
    • payment_method_kind
    • total_payment_count_2025
    • count_credit_equals_net
    • count_credit_equals_payment_plus_refund
    • count_other_mismatch
    • count_no_ledger_entries
    • pct_clean (count_credit_equals_net + count_credit_equals_payment_plus_refund, as % of total)
  4. Ines writes the SQL

    The engineer · 1 dry run on the empty schema, then the submission

    Dry run 1 · STATUS: COMPILES (dry run on the empty schema, no data read)
    WITH fx AS (
      SELECT quote_code, as_of, rate
      FROM exchange_rates
      WHERE base_code = 'EUR'
    ),
    payments_2025 AS (
      SELECT p.id, p.payment_method_id, p.amount, p.amount_refunded, p.currency_code, p.captured_at
      FROM payments p
      WHERE p.status IN ('captured', 'refunded', 'partially_refunded')
        AND p.captured_at >= DATE '2025-01-01'
        AND p.captured_at < DATE '2026-01-01'
    ),
    ledger_agg AS (
      SELECT
        le.payment_id,
        SUM(
          CASE WHEN le.direction = 'credit'
            THEN le.amount * COALESCE(fx.rate, CASE WHEN le.currency_code = 'EUR' THEN 1 END)
            ELSE 0
          END
        ) AS credit_eur,
        COUNT(*) AS entry_count
      FROM ledger_entries le
      LEFT JOIN fx ON fx.quote_code = le.currency_code AND fx.as_of = DATE(le.occurred_at)
      WHERE le.payment_id IS NOT NULL
      GROUP BY le.payment_id
    ),
    calc AS (
      SELECT
        p.id,
        COALESCE(pm.kind, 'unknown') AS payment_method_kind,
        p.amount * COALESCE(fx_p.rate, CASE WHEN p.currency_code = 'EUR' THEN 1 END) AS payment_amount_eur,
        p.amount_refunded * COALESCE(fx_p.rate, CASE WHEN p.currency_code = 'EUR' THEN 1 END) AS refunded_amount_eur,
        la.credit_eur,
        la.entry_count
      FROM payments_2025 p
      LEFT JOIN payment_methods pm ON pm.id = p.payment_method_id
      LEFT JOIN fx fx_p ON fx_p.quote_code = p.currency_code AND fx_p.as_of = DATE(p.captured_at)
      LEFT JOIN ledger_agg la ON la.payment_id = p.id
    ),
    classified AS (
      SELECT
        id,
        payment_method_kind,
        CASE
          WHEN entry_count IS NULL OR entry_count = 0 THEN 'no_ledger_entries'
          WHEN ABS(credit_eur - (payment_amount_eur - refunded_amount_eur))
               <= GREATEST(1.0, 0.01 * ABS(payment_amount_eur - refunded_amount_eur))
            THEN 'credit_equals_net'
          WHEN ABS(credit_eur - (payment_amount_eur + refunded_amount_eur))
               <= GREATEST(1.0, 0.01 * ABS(payment_amount_eur + refunded_amount_eur))
            THEN 'credit_equals_payment_plus_refund'
          ELSE 'other_mismatch'
        END AS classification
      FROM calc
    )
    SELECT
      payment_method_kind,
      COUNT(*) AS total_payment_count_2025,
      SUM(CASE WHEN classification = 'credit_equals_net' THEN 1 ELSE 0 END) AS count_credit_equals_net,
      SUM(CASE WHEN classification = 'credit_equals_payment_plus_refund' THEN 1 ELSE 0 END) AS count_credit_equals_payment_plus_refund,
      SUM(CASE WHEN classification = 'other_mismatch' THEN 1 ELSE 0 END) AS count_other_mismatch,
      SUM(CASE WHEN classification = 'no_ledger_entries' THEN 1 ELSE 0 END) AS count_no_ledger_entries,
      ROUND(
        100.0 * SUM(CASE WHEN classification IN ('credit_equals_net', 'credit_equals_payment_plus_refund') THEN 1 ELSE 0 END)
        / COUNT(*),
        1
      ) AS pct_clean
    FROM classified
    GROUP BY payment_method_kind
    ORDER BY total_payment_count_2025 DESC, payment_method_kind ASC

    “Query compiles with the expected columns. Submitting now.”

    Submitted · the SQL of the last dry run, unchanged · Submitted to tonight's batch. Your work on this request is done.

    “Submitted. The report groups all qualifying 2025 payments by payment_methods.kind, giving Kofi the full denominator (total_payment_count_2025) alongside each reconciliation outcome and a clean-rate percentage, so he can see whether bank_transfer's 19 flagged mismatches are a large share of a small population or a tiny fraction of a much bigger one — directly answering the CFO's "systemic vs. rare exception" question.”

  5. The report comes back overnight

    As Kofi Mensah saw it, from the small dataset the agents worked on

    payment_method_kind | total_payment_count_2025 | count_credit_equals_net | count_credit_equals_payment_plus_refund | count_other_mismatch | count_no_ledger_entries | pct_clean
    --------------------+--------------------------+-------------------------+-----------------------------------------+----------------------+-------------------------+----------
    card                |                    12964 |                   10540 |                                    2228 |                  196 |                       0 |      98.5
    wallet              |                     4051 |                    3477 |                                     518 |                   56 |                       0 |      98.6
    bank_transfer       |                     2716 |                    2443 |                                     219 |                   54 |                       0 |      98.0
    credit              |                     1207 |                    1153 |                                      50 |                    4 |                       0 |      99.7
    unknown             |                      115 |                      15 |                                       0 |                    0 |                     100 |      13.0
    (5 rows)
  6. What came of it

    The memo and the queries that followed; links found by title, so inferred

    Kofi Mensah's memo to Tobias Lindqvist at the end of the week:

    • Confident: the accounting logic is sound and ~98-99% of 2025 payments (card, wallet, bank_transfer, credit) reconcile cleanly ("Ledger Reconciliation Outcome by Payment Method").

    It builds on:

  7. It becomes benchmark query q231

    Changed only where the benchmark needs the same result on every system

    • spellingdate cast (2×)
    • numericsdocs/NUMERICS.md: rounding removed; results keep full precision
    • made explicita selected t.col gets AS col, its standard name made explicit (10×)
    • determinismthe standard leaves the place of NULLs in a sort to the implementation: NULLS LAST ascending, NULLS FIRST descending, as in the reference results (2×)
    The benchmark text, against the submitted SQL
    WITH fx AS (  SELECT quote_code, as_of, rate  FROM exchange_rates  WHERE base_code = 'EUR'),payments_2025 AS (  SELECT p.id, p.payment_method_id, p.amount, p.amount_refunded, p.currency_code, p.captured_at  SELECT p.id AS id, p.payment_method_id AS payment_method_id, p.amount AS amount, p.amount_refunded AS amount_refunded, p.currency_code AS currency_code, p.captured_at AS captured_at  FROM payments p  WHERE p.status IN ('captured', 'refunded', 'partially_refunded')    AND p.captured_at >= DATE '2025-01-01'    AND p.captured_at < DATE '2026-01-01'),ledger_agg AS (  SELECT    le.payment_id,    le.payment_id AS payment_id,    SUM(      CASE WHEN le.direction = 'credit'        THEN le.amount * COALESCE(fx.rate, CASE WHEN le.currency_code = 'EUR' THEN 1 END)        ELSE 0      END    ) AS credit_eur,    COUNT(*) AS entry_count  FROM ledger_entries le  LEFT JOIN fx ON fx.quote_code = le.currency_code AND fx.as_of = DATE(le.occurred_at)  LEFT JOIN fx ON fx.quote_code = le.currency_code AND fx.as_of = CAST(le.occurred_at AS DATE)  WHERE le.payment_id IS NOT NULL  GROUP BY le.payment_id),calc AS (  SELECT    p.id,    p.id AS id,    COALESCE(pm.kind, 'unknown') AS payment_method_kind,    p.amount * COALESCE(fx_p.rate, CASE WHEN p.currency_code = 'EUR' THEN 1 END) AS payment_amount_eur,    p.amount_refunded * COALESCE(fx_p.rate, CASE WHEN p.currency_code = 'EUR' THEN 1 END) AS refunded_amount_eur,    la.credit_eur,    la.entry_count    la.credit_eur AS credit_eur,    la.entry_count AS entry_count  FROM payments_2025 p  LEFT JOIN payment_methods pm ON pm.id = p.payment_method_id  LEFT JOIN fx fx_p ON fx_p.quote_code = p.currency_code AND fx_p.as_of = DATE(p.captured_at)  LEFT JOIN fx fx_p ON fx_p.quote_code = p.currency_code AND fx_p.as_of = CAST(p.captured_at AS DATE)  LEFT JOIN ledger_agg la ON la.payment_id = p.id),classified AS (  SELECT    id,    payment_method_kind,    CASE      WHEN entry_count IS NULL OR entry_count = 0 THEN 'no_ledger_entries'      WHEN ABS(credit_eur - (payment_amount_eur - refunded_amount_eur))           <= GREATEST(1.0, 0.01 * ABS(payment_amount_eur - refunded_amount_eur))        THEN 'credit_equals_net'      WHEN ABS(credit_eur - (payment_amount_eur + refunded_amount_eur))           <= GREATEST(1.0, 0.01 * ABS(payment_amount_eur + refunded_amount_eur))        THEN 'credit_equals_payment_plus_refund'      ELSE 'other_mismatch'    END AS classification  FROM calc)SELECT  payment_method_kind,  COUNT(*) AS total_payment_count_2025,  SUM(CASE WHEN classification = 'credit_equals_net' THEN 1 ELSE 0 END) AS count_credit_equals_net,  SUM(CASE WHEN classification = 'credit_equals_payment_plus_refund' THEN 1 ELSE 0 END) AS count_credit_equals_payment_plus_refund,  SUM(CASE WHEN classification = 'other_mismatch' THEN 1 ELSE 0 END) AS count_other_mismatch,  SUM(CASE WHEN classification = 'no_ledger_entries' THEN 1 ELSE 0 END) AS count_no_ledger_entries,  ROUND(    100.0 * SUM(CASE WHEN classification IN ('credit_equals_net', 'credit_equals_payment_plus_refund') THEN 1 ELSE 0 END)    / COUNT(*),    1  ) AS pct_clean  100.0 * SUM(CASE WHEN classification IN ('credit_equals_net', 'credit_equals_payment_plus_refund') THEN 1 ELSE 0 END)  / COUNT(*) AS pct_cleanFROM classifiedGROUP BY payment_method_kindORDER BY total_payment_count_2025 DESC, payment_method_kind ASCORDER BY total_payment_count_2025 DESC NULLS FIRST, payment_method_kind ASC NULLS LAST
    WITH fx AS (
      SELECT quote_code, as_of, rate
      FROM exchange_rates
      WHERE base_code = 'EUR'
    ),
    payments_2025 AS (
      SELECT p.id AS id, p.payment_method_id AS payment_method_id, p.amount AS amount, p.amount_refunded AS amount_refunded, p.currency_code AS currency_code, p.captured_at AS captured_at
      FROM payments p
      WHERE p.status IN ('captured', 'refunded', 'partially_refunded')
        AND p.captured_at >= DATE '2025-01-01'
        AND p.captured_at < DATE '2026-01-01'
    ),
    ledger_agg AS (
      SELECT
        le.payment_id AS payment_id,
        SUM(
          CASE WHEN le.direction = 'credit'
            THEN le.amount * COALESCE(fx.rate, CASE WHEN le.currency_code = 'EUR' THEN 1 END)
            ELSE 0
          END
        ) AS credit_eur,
        COUNT(*) AS entry_count
      FROM ledger_entries le
      LEFT JOIN fx ON fx.quote_code = le.currency_code AND fx.as_of = CAST(le.occurred_at AS DATE)
      WHERE le.payment_id IS NOT NULL
      GROUP BY le.payment_id
    ),
    calc AS (
      SELECT
        p.id AS id,
        COALESCE(pm.kind, 'unknown') AS payment_method_kind,
        p.amount * COALESCE(fx_p.rate, CASE WHEN p.currency_code = 'EUR' THEN 1 END) AS payment_amount_eur,
        p.amount_refunded * COALESCE(fx_p.rate, CASE WHEN p.currency_code = 'EUR' THEN 1 END) AS refunded_amount_eur,
        la.credit_eur AS credit_eur,
        la.entry_count AS entry_count
      FROM payments_2025 p
      LEFT JOIN payment_methods pm ON pm.id = p.payment_method_id
      LEFT JOIN fx fx_p ON fx_p.quote_code = p.currency_code AND fx_p.as_of = CAST(p.captured_at AS DATE)
      LEFT JOIN ledger_agg la ON la.payment_id = p.id
    ),
    classified AS (
      SELECT
        id,
        payment_method_kind,
        CASE
          WHEN entry_count IS NULL OR entry_count = 0 THEN 'no_ledger_entries'
          WHEN ABS(credit_eur - (payment_amount_eur - refunded_amount_eur))
               <= GREATEST(1.0, 0.01 * ABS(payment_amount_eur - refunded_amount_eur))
            THEN 'credit_equals_net'
          WHEN ABS(credit_eur - (payment_amount_eur + refunded_amount_eur))
               <= GREATEST(1.0, 0.01 * ABS(payment_amount_eur + refunded_amount_eur))
            THEN 'credit_equals_payment_plus_refund'
          ELSE 'other_mismatch'
        END AS classification
      FROM calc
    )
    SELECT
      payment_method_kind,
      COUNT(*) AS total_payment_count_2025,
      SUM(CASE WHEN classification = 'credit_equals_net' THEN 1 ELSE 0 END) AS count_credit_equals_net,
      SUM(CASE WHEN classification = 'credit_equals_payment_plus_refund' THEN 1 ELSE 0 END) AS count_credit_equals_payment_plus_refund,
      SUM(CASE WHEN classification = 'other_mismatch' THEN 1 ELSE 0 END) AS count_other_mismatch,
      SUM(CASE WHEN classification = 'no_ledger_entries' THEN 1 ELSE 0 END) AS count_no_ledger_entries,
      100.0 * SUM(CASE WHEN classification IN ('credit_equals_net', 'credit_equals_payment_plus_refund') THEN 1 ELSE 0 END)
      / COUNT(*) AS pct_clean
    FROM classified
    GROUP BY payment_method_kind
    ORDER BY total_payment_count_2025 DESC NULLS FIRST, payment_method_kind ASC NULLS LAST
    100 ms1 s10 sHyper1.02 sDuckDB1.01 sGizmoSQL788 msclickhouse_brew1.65 sFirebolterrorDataFusion1.39 sClickHouse1.58 s
    • Firebolt{ "errors": [ { "description": "Line 18, Column 24: Operations between decimals with different precision and scale is not supported at the moment. Explicitly cast one of the decimals to other decimal precision and scale." } ], "query": { "query_id": "ef1b2928-0b38-4ca2-8fe2-b48880f0c5ef", "query_lab
  8. Everything, as recorded

    The agents' own records, as the role play wrote them; only the personal data of the person who ran it is redacted

    Ines's whole session, 7 turns
    • The request, as Ines received it
      Report request from Kofi Mensah (analyst for the Chief Financial Officer):
      
      Title: Ledger Reconciliation Outcome by Payment Method, All 2025 Payments
      Question: Is bank_transfer systemically more prone to ledger mismatches as a payment channel, or are the 19 flagged payments a rare exception within a much larger, mostly-clean population?
      Grain: one payment_methods.kind, across ALL 2025 captured payments (not just the mismatched ones)
      Columns:
      - payment_method_kind
      - total_payment_count_2025
      - count_credit_equals_net
      - count_credit_equals_payment_plus_refund
      - count_other_mismatch
      - count_no_ledger_entries
      - pct_clean (count_credit_equals_net + count_credit_equals_payment_plus_refund, as % of total)
      Details: Same reconciliation classification used all week (payments captured/refunded/partially_refunded in 2025; per-payment ledger credit total in EUR vs net_amount_eur and payment+refund_eur with 1%-or-€1 tolerance; 'no ledger entries' when zero linked ledger_entries rows). This time classify and count ALL qualifying 2025 payments (not pre-filtered to any mismatch category), joined to payment_methods.kind (null/missing as 'unknown'), and group by kind. Order by total_payment_count_2025 descending.
      
      Check your query with the warehouse's dry_run tool, then hand it in with submit.
    • Ines calls dry_run
      WITH fx AS (
        SELECT quote_code, as_of, rate
        FROM exchange_rates
        WHERE base_code = 'EUR'
      ),
      payments_2025 AS (
        SELECT p.id, p.payment_method_id, p.amount, p.amount_refunded, p.currency_code, p.captured_at
        FROM payments p
        WHERE p.status IN ('captured', 'refunded', 'partially_refunded')
          AND p.captured_at >= DATE '2025-01-01'
          AND p.captured_at < DATE '2026-01-01'
      ),
      ledger_agg AS (
        SELECT
          le.payment_id,
          SUM(
            CASE WHEN le.direction = 'credit'
              THEN le.amount * COALESCE(fx.rate, CASE WHEN le.currency_code = 'EUR' THEN 1 END)
              ELSE 0
            END
          ) AS credit_eur,
          COUNT(*) AS entry_count
        FROM ledger_entries le
        LEFT JOIN fx ON fx.quote_code = le.currency_code AND fx.as_of = DATE(le.occurred_at)
        WHERE le.payment_id IS NOT NULL
        GROUP BY le.payment_id
      ),
      calc AS (
        SELECT
          p.id,
          COALESCE(pm.kind, 'unknown') AS payment_method_kind,
          p.amount * COALESCE(fx_p.rate, CASE WHEN p.currency_code = 'EUR' THEN 1 END) AS payment_amount_eur,
          p.amount_refunded * COALESCE(fx_p.rate, CASE WHEN p.currency_code = 'EUR' THEN 1 END) AS refunded_amount_eur,
          la.credit_eur,
          la.entry_count
        FROM payments_2025 p
        LEFT JOIN payment_methods pm ON pm.id = p.payment_method_id
        LEFT JOIN fx fx_p ON fx_p.quote_code = p.currency_code AND fx_p.as_of = DATE(p.captured_at)
        LEFT JOIN ledger_agg la ON la.payment_id = p.id
      ),
      classified AS (
        SELECT
          id,
          payment_method_kind,
          CASE
            WHEN entry_count IS NULL OR entry_count = 0 THEN 'no_ledger_entries'
            WHEN ABS(credit_eur - (payment_amount_eur - refunded_amount_eur))
                 <= GREATEST(1.0, 0.01 * ABS(payment_amount_eur - refunded_amount_eur))
              THEN 'credit_equals_net'
            WHEN ABS(credit_eur - (payment_amount_eur + refunded_amount_eur))
                 <= GREATEST(1.0, 0.01 * ABS(payment_amount_eur + refunded_amount_eur))
              THEN 'credit_equals_payment_plus_refund'
            ELSE 'other_mismatch'
          END AS classification
        FROM calc
      )
      SELECT
        payment_method_kind,
        COUNT(*) AS total_payment_count_2025,
        SUM(CASE WHEN classification = 'credit_equals_net' THEN 1 ELSE 0 END) AS count_credit_equals_net,
        SUM(CASE WHEN classification = 'credit_equals_payment_plus_refund' THEN 1 ELSE 0 END) AS count_credit_equals_payment_plus_refund,
        SUM(CASE WHEN classification = 'other_mismatch' THEN 1 ELSE 0 END) AS count_other_mismatch,
        SUM(CASE WHEN classification = 'no_ledger_entries' THEN 1 ELSE 0 END) AS count_no_ledger_entries,
        ROUND(
          100.0 * SUM(CASE WHEN classification IN ('credit_equals_net', 'credit_equals_payment_plus_refund') THEN 1 ELSE 0 END)
          / COUNT(*),
          1
        ) AS pct_clean
      FROM classified
      GROUP BY payment_method_kind
      ORDER BY total_payment_count_2025 DESC, payment_method_kind ASC
    • The warehouse answers
      STATUS: COMPILES (dry run on the empty schema, no data read)
      COLUMNS: payment_method_kind, total_payment_count_2025, count_credit_equals_net, count_credit_equals_payment_plus_refund, count_other_mismatch, count_no_ledger_entries, pct_clean
    • InesQuery compiles with the expected columns. Submitting now.
    • Ines calls submit
      WITH fx AS (
        SELECT quote_code, as_of, rate
        FROM exchange_rates
        WHERE base_code = 'EUR'
      ),
      payments_2025 AS (
        SELECT p.id, p.payment_method_id, p.amount, p.amount_refunded, p.currency_code, p.captured_at
        FROM payments p
        WHERE p.status IN ('captured', 'refunded', 'partially_refunded')
          AND p.captured_at >= DATE '2025-01-01'
          AND p.captured_at < DATE '2026-01-01'
      ),
      ledger_agg AS (
        SELECT
          le.payment_id,
          SUM(
            CASE WHEN le.direction = 'credit'
              THEN le.amount * COALESCE(fx.rate, CASE WHEN le.currency_code = 'EUR' THEN 1 END)
              ELSE 0
            END
          ) AS credit_eur,
          COUNT(*) AS entry_count
        FROM ledger_entries le
        LEFT JOIN fx ON fx.quote_code = le.currency_code AND fx.as_of = DATE(le.occurred_at)
        WHERE le.payment_id IS NOT NULL
        GROUP BY le.payment_id
      ),
      calc AS (
        SELECT
          p.id,
          COALESCE(pm.kind, 'unknown') AS payment_method_kind,
          p.amount * COALESCE(fx_p.rate, CASE WHEN p.currency_code = 'EUR' THEN 1 END) AS payment_amount_eur,
          p.amount_refunded * COALESCE(fx_p.rate, CASE WHEN p.currency_code = 'EUR' THEN 1 END) AS refunded_amount_eur,
          la.credit_eur,
          la.entry_count
        FROM payments_2025 p
        LEFT JOIN payment_methods pm ON pm.id = p.payment_method_id
        LEFT JOIN fx fx_p ON fx_p.quote_code = p.currency_code AND fx_p.as_of = DATE(p.captured_at)
        LEFT JOIN ledger_agg la ON la.payment_id = p.id
      ),
      classified AS (
        SELECT
          id,
          payment_method_kind,
          CASE
            WHEN entry_count IS NULL OR entry_count = 0 THEN 'no_ledger_entries'
            WHEN ABS(credit_eur - (payment_amount_eur - refunded_amount_eur))
                 <= GREATEST(1.0, 0.01 * ABS(payment_amount_eur - refunded_amount_eur))
              THEN 'credit_equals_net'
            WHEN ABS(credit_eur - (payment_amount_eur + refunded_amount_eur))
                 <= GREATEST(1.0, 0.01 * ABS(payment_amount_eur + refunded_amount_eur))
              THEN 'credit_equals_payment_plus_refund'
            ELSE 'other_mismatch'
          END AS classification
        FROM calc
      )
      SELECT
        payment_method_kind,
        COUNT(*) AS total_payment_count_2025,
        SUM(CASE WHEN classification = 'credit_equals_net' THEN 1 ELSE 0 END) AS count_credit_equals_net,
        SUM(CASE WHEN classification = 'credit_equals_payment_plus_refund' THEN 1 ELSE 0 END) AS count_credit_equals_payment_plus_refund,
        SUM(CASE WHEN classification = 'other_mismatch' THEN 1 ELSE 0 END) AS count_other_mismatch,
        SUM(CASE WHEN classification = 'no_ledger_entries' THEN 1 ELSE 0 END) AS count_no_ledger_entries,
        ROUND(
          100.0 * SUM(CASE WHEN classification IN ('credit_equals_net', 'credit_equals_payment_plus_refund') THEN 1 ELSE 0 END)
          / COUNT(*),
          1
        ) AS pct_clean
      FROM classified
      GROUP BY payment_method_kind
      ORDER BY total_payment_count_2025 DESC, payment_method_kind ASC
    • The warehouse answers
      Submitted to tonight's batch. Your work on this request is done.
    • InesSubmitted. The report groups all qualifying 2025 payments by `payment_methods.kind`, giving Kofi the full denominator (total_payment_count_2025) alongside each reconciliation outcome and a clean-rate percentage, so he can see whether bank_transfer's 19 flagged mismatches are a large share of a small population or a tiny fraction of a much bigger one — directly answering the CFO's "systemic vs. rare exception" question.