Retail · SQL
Negative stock identification and backorder exposure ranking by store
Independent grading: 92/100(verify, opens in a new tab)
Problem
Chidi Okafor at Meridian Retail (simulated retailer) was receiving complaints from store managers about empty shelves. Inventory records were showing negative stock quantities, meaning items were being sold beyond available supply. The task was to identify all affected products with store details and rank stores by total financial exposure.
What I did
Joining `inventory` to `stores` and `products` gives the right grain: one row per product-store combination in negative stock. A `WHERE i.stock_qty < 0` filter isolates the problem records. The exposure formula `ABS(i.stock_qty) * (p.list_price_cents / 100.0)` converts the unit shortfall into a naira value using floating-point division, with `.0` preventing integer truncation. Aggregating at store level with `COUNT(DISTINCT p.product_id)`, total units oversold, and summed exposure, then ordering by exposure descending, gives Chidi a prioritised action list rather than a flat record dump.
Finding
Sixty-six negative-stock records across 17 stores were identified, with Meridian Kano carrying the highest backorder exposure at NGN 3.83M.
Outcome
Chidi received a ranked store table showing exactly where to direct replenishment effort first, with the financial scale of each location's shortfall visible at a glance.
SELECT s.store_id, s.name, s.city, COUNT(DISTINCT p.product_id) AS products_in_negative_stock, SUM(ABS(i.stock_qty)) AS total_units_oversold, SUM(ABS(i.stock_qty) * (p.list_price_cents / 100.0)) AS total_backorder_exposure FROM inventory i JOIN stores s ON i.store_id = s.store_id JOIN products p ON i.product_id = p.product_id WHERE i.stock_qty < 0 GROUP BY s.store_id, s.name, s.city ORDER BY total_backorder_exposure DESC;
The exposure calculation multiplies the absolute unit shortfall by the per-unit naira price, converting a stock count into a financial risk figure that operations management can act on directly.
Next step
Filtering further by product category would show whether the negative stock is concentrated in a particular line, which would point to a supplier or ordering process issue rather than a store-level one.
- Multi-table JOIN chains in SQL
- GROUP BY with ORDER BY for ranked summaries
- Cents-to-currency conversion in SQL arithmetic
- Conditional COUNT with FILTER in PostgreSQL