Retail · SQL
Reconciling a NGN 18.4M revenue discrepancy for a board presentation
Independent grading: 97/100(verify, opens in a new tab)
Problem
The CFO at Meridian Retail (simulated retailer) flagged a conflict between two systems: the Finance platform showed NGN 38.5M for October 2023 while the sales dashboard showed NGN 56.9M. Before a board presentation, I was asked to pull October orders broken down by status, showing both gross and net revenue and making the gap between the two figures explicit.
What I did
To scope the data safely to October, I used a half-open interval on the created_at column, avoiding any boundary ambiguity from time components. Within a single SELECT, I computed gross revenue as a plain SUM and net revenue using a FILTER clause that excluded cancelled, returned, and refunded orders, so both figures came from one table scan. A UNION ALL block appended a TOTAL row beneath the per-status breakdown, giving the board exactly two reconciliation anchors alongside the full detail. The difference_naira column was derived inline, making which statuses drove the gap readable without any supporting narrative.
Finding
Gross revenue for October 2023 was NGN 56,876,792.48, matching the sales dashboard, and net revenue was NGN 38,450,382.35, matching Finance, with the NGN 18,426,410.13 gap accounted for entirely by cancelled, returned, and refunded orders.
Outcome
The CFO received a single query result that confirmed both system figures were correct and showed the board exactly which order statuses produced the difference.
SELECT
status::text AS status,
COUNT(*) AS order_count,
SUM(total_cents) / 100.0 AS gross_naira,
SUM(total_cents) FILTER (
WHERE status NOT IN ('cancelled', 'returned', 'refunded')
) / 100.0 AS net_naira,
(
SUM(total_cents)
-SUM(total_cents) FILTER (WHERE status NOT IN
('cancelled', 'returned', 'refunded')
)
) / 100.0 AS difference_naira
FROM orders
WHERE created_at >= '2023-10-01'
AND created_at < '2023-11-01'
GROUP BY statusThis block computes gross naira, net naira, and their difference in one pass using the FILTER clause, removing the need for a subquery or CTE while keeping the per-status logic transparent.
Next step
A useful follow-on would be breaking down the cancelled and returned orders by product category to see whether the revenue gap is concentrated in a particular line of stock.
- half-open interval date filtering in SQL
- FILTER clause with conditional aggregation
- UNION ALL totals row for reconciliation summaries
- derived difference columns within a single query
- status-based gross vs net revenue separation
- cents-to-currency unit conversion in SQL