SQL Quest

Lessons, hints, explained solutions, the in-browser PostgreSQL editor and practice answer checks in your browser are available. Graded assessments, recorded progress from answer checks and new certificates aren't available yet.

Sahra Logistics warehousing and transport

Sahra Logistics (fictional) · 12 tables · 92,456 rows · version 1

Open in the playground

Two years (2024–2025) of logistics operations. Stock side: suppliers, products, purchase orders and their lines, an inventory movement ledger (opening balances, receipts, monthly outbound totals and adjustments) and month-end inventory snapshots. Transport side: customers, carriers, routes, about 12,000 shipments and their scan events. Built for operations analytics: on-time delivery, carrier performance and seasonality, stock levels, reorder alerts and supplier lead times. Amounts are in SAR.

The documentation is open to everyone. Querying this dataset in the playground is included with Formula Quest membership; lessons that use it follow their own access.

Relationships

warehouses6PKwarehouse_idwarehouse_codewarehouse_namecitycapacity_palletsopened_onsuppliers20PKsupplier_idsupplier_namecountrycitylead_time_daysproducts60PKproduct_idFKsupplier_idskuproduct_namecategoryunit_weight_kgunit_costreorder_levelis_activecustomers180PKcustomer_idcustomer_namesegmentcitycustomer_sincecarriers8PKcarrier_idcarrier_namemoderatingroutes67PKroute_idorigin_citydestination_citymodedistance_kmstandard_daysshipments12,000PKshipment_idFKwarehouse_idFKcustomer_idFKcarrier_idFKroute_idcreated_atshipped_atpromised_datedelivered_at+ 4 more columnsshipment_events63,323PKevent_idFKshipment_idevent_timeevent_typelocationdetailspurchase_orders1,674PKpo_idFKsupplier_idFKwarehouse_idpo_numberordered_onexpected_onreceived_onstatuspurchase_order_lines2,995PKpo_line_idFKpo_idFKproduct_idquantity_orderedquantity_receivedunit_costinventory_movements7,702PKmovement_idFKwarehouse_idFKproduct_idFKpo_line_idmovement_datemovement_typequantityadjustment_reasoninventory_snapshots4,421PKsnapshot_datePKwarehouse_idPKproduct_idon_handallocated
Arrows point from a foreign key to the table it references. PK = primary key, FK = foreign key. Numbers are row counts.

Sample queries

On-time delivery rate by carrier
SELECT c.carrier_name, c.mode,
       count(*) AS delivered,
       round(100.0 * count(*) FILTER (WHERE s.delivered_at::date <= s.promised_date) / count(*), 1) AS on_time_pct
FROM shipments s
JOIN carriers c ON c.carrier_id = s.carrier_id
WHERE s.status = 'delivered'
GROUP BY c.carrier_name, c.mode
ORDER BY on_time_pct DESC;
Shipments by status
SELECT status, count(*) AS shipments, count(*) FILTER (WHERE delivered_at IS NULL) AS without_delivery_time
FROM shipments
GROUP BY status
ORDER BY shipments DESC;
Products below reorder level at the end of 2025
SELECT w.warehouse_code, p.sku, p.product_name, i.on_hand, i.allocated, p.reorder_level
FROM inventory_snapshots i
JOIN products p ON p.product_id = i.product_id
JOIN warehouses w ON w.warehouse_id = i.warehouse_id
WHERE i.snapshot_date = DATE '2025-12-31'
  AND p.is_active
  AND i.on_hand - i.allocated < p.reorder_level
ORDER BY i.on_hand - i.allocated - p.reorder_level;
Stock on hand from the movement ledger
SELECT warehouse_id, product_id, sum(quantity) AS on_hand
FROM inventory_movements
WHERE movement_date <= DATE '2025-06-30'
GROUP BY warehouse_id, product_id
ORDER BY warehouse_id, product_id
LIMIT 20;
Supplier delivery performance
SELECT su.supplier_name,
       count(*) AS received_orders,
       round(avg(po.received_on - po.ordered_on), 1) AS avg_lead_days,
       count(*) FILTER (WHERE po.received_on > po.expected_on) AS late_orders
FROM purchase_orders po
JOIN suppliers su ON su.supplier_id = po.supplier_id
WHERE po.received_on IS NOT NULL
GROUP BY su.supplier_name
ORDER BY late_orders DESC;

Data dictionary

warehouses

6 rows · primary key (warehouse_id)

Warehouses / distribution centres.

ColumnTypeNull?KeyDescription
warehouse_idintegerno PKUnique warehouse number.
warehouse_codetextnouniqueShort code (e.g. RUH1).
warehouse_nametextnoName.
citytextnoCity (the origin city of its routes).
capacity_palletsintegernoStorage capacity in pallet positions.
opened_ondatenoOpening date (Riyadh South opened during the data period).

suppliers

20 rows · primary key (supplier_id)

Suppliers the company buys stock from.

ColumnTypeNull?KeyDescription
supplier_idintegerno PKUnique supplier number.
supplier_nametextnouniqueName (fictional).
countrychar(2)noISO country code.
citytextnoCity.
lead_time_daysintegernoContracted days from order to delivery.

products

60 rows · primary key (product_id)

Stock-keeping units (SKUs). unit_cost is the current standard cost.

ColumnTypeNull?KeyDescription
product_idintegerno PKUnique product number.
skutextnouniqueStock-keeping unit code.
product_nametextnoProduct name (pack size included).
categorytextnoProduct category.
supplier_idintegerno suppliers.supplier_idUsual supplier.
unit_weight_kgnumeric(6,3)noWeight of one unit in kg.
unit_costnumeric(12,2)noCurrent standard cost per unit in SAR.
reorder_levelintegernoReorder when available stock (on_hand − allocated) falls below this, per warehouse.
is_activebooleannoFALSE for discontinued products (no longer reordered).

customers

180 rows · primary key (customer_id)

Business customers receiving shipments.

ColumnTypeNull?KeyDescription
customer_idintegerno PKUnique customer number.
customer_nametextnoCompany name (fictional).
segmenttextnoretail, wholesale, ecommerce, hospitality or construction.
citytextnoDelivery city (Saudi Arabia or GCC).
customer_sincedatenoContract start date.

carriers

8 rows · primary key (carrier_id)

Transport companies (including the in-house Sahra Fleet).

ColumnTypeNull?KeyDescription
carrier_idintegerno PKUnique carrier number.
carrier_nametextnouniqueName (fictional).
modetextnoroad, air or sea.
ratingnumeric(5,2)noProcurement team's rating (1–5) at contract renewal; not computed from the data.

routes

67 rows · primary key (route_id)

Lanes: origin city, destination city and transport mode, with the standard transit time.

ColumnTypeNull?KeyDescription
route_idintegerno PKUnique route number.
origin_citytextnoOrigin (a warehouse city).
destination_citytextnoDestination city.
modetextnoroad, air or sea.
distance_kmintegernoDistance in km (25 for same-city deliveries).
standard_daysintegernoStandard transit days used to set promised_date.

shipments

12,000 rows · primary key (shipment_id)

Customer shipments (one consignment from a warehouse to a customer). Shipment-level only: no product lines.

ColumnTypeNull?KeyDescription
shipment_idintegerno PKUnique shipment number (ascending with creation time).
warehouse_idintegerno warehouses.warehouse_idDispatching warehouse.
customer_idintegerno customers.customer_idReceiving customer.
carrier_idintegerno carriers.carrier_idCarrier that moves the shipment.
route_idintegerno routes.route_idLane used (origin, destination, mode).
created_attimestampnoWhen the shipment order was created in the warehouse system.
shipped_attimestampyesWhen it left the warehouse. NULL = not dispatched yet (status created).
promised_datedatenoDelivery date promised to the customer.
delivered_attimestampyesProof-of-delivery time. NULL unless status = 'delivered'.
statustextnoStatus on 2025-12-31: created, in_transit, delayed (in transit and past promised_date), delivered (on time or late), lost or returned.
packagesintegernoNumber of packages / pallets.
weight_kgnumeric(12,2)yesChargeable weight in kg. NULL until weighed at dispatch.
freight_costnumeric(12,2)noCarrier charge in SAR (0 for goodwill re-deliveries).

shipment_events

63,323 rows · primary key (event_id)

Tracking scans for each shipment, in time order: picked, packed, dispatched, arrived_hub, out_for_delivery, delivered, plus exception and returned events.

ColumnTypeNull?KeyDescription
event_idintegerno PKUnique event number (ascending with time).
shipment_idintegerno shipments.shipment_idThe shipment scanned.
event_timetimestampnoWhen the scan happened.
event_typetextnopicked, packed, dispatched, arrived_hub, out_for_delivery, delivered, exception or returned.
locationtextnoCity where the scan happened.
detailstextyesFree text for exceptions and returns (e.g. 'Weather delay'). NULL for routine scans.

purchase_orders

1,674 rows · primary key (po_id)

Purchase orders to suppliers, one per supplier and receiving warehouse.

ColumnTypeNull?KeyDescription
po_idintegerno PKUnique purchase order number.
po_numbertextnouniqueDocument number (PO-YY-#####).
supplier_idintegerno suppliers.supplier_idSupplier.
warehouse_idintegerno warehouses.warehouse_idReceiving warehouse.
ordered_ondatenoOrder date.
expected_ondatenoExpected delivery date (ordered_on + supplier lead time).
received_ondateyesDate the goods were received. NULL for open or cancelled orders.
statustextnoopen, received, partially_received (closed short) or cancelled.

purchase_order_lines

2,995 rows · primary key (po_line_id)

Products ordered on each purchase order.

ColumnTypeNull?KeyDescription
po_line_idintegerno PKUnique line number.
po_idintegerno purchase_orders.po_idThe purchase order.
product_idintegerno products.product_idProduct ordered.
quantity_orderedintegernoUnits ordered.
quantity_receivedintegernoUnits received (0 for open or cancelled orders; less than ordered for partial deliveries).
unit_costnumeric(12,2)noPrice paid per unit in SAR on this order.

inventory_movements

7,702 rows · primary key (movement_id)

Stock ledger: every change to on-hand quantity. on_hand at a date = sum(quantity) of all movements up to that date for the warehouse and product.

ColumnTypeNull?KeyDescription
movement_idintegerno PKUnique movement number (ascending with date).
warehouse_idintegerno warehouses.warehouse_idWarehouse whose stock changed.
product_idintegerno products.product_idProduct whose stock changed.
movement_datedatenoPosting date.
movement_typetextnoopening (balance on 2023-12-31), receipt (from a purchase order), outbound (monthly total shipped to customers, posted at month end) or adjustment.
quantityintegernoSigned units: positive adds stock, negative removes it.
po_line_idintegeryes purchase_order_lines.po_line_idFor receipts: the purchase order line received. NULL otherwise.
adjustment_reasontextyesFor adjustments: shrinkage, damaged, expired or cycle_count (can be + or −). NULL otherwise.

inventory_snapshots

4,421 rows · primary key (snapshot_date, warehouse_id, product_id)

Month-end stock position per warehouse and product (only products the warehouse stocks).

ColumnTypeNull?KeyDescription
snapshot_datedateno PKLast day of the month.
warehouse_idintegerno PK warehouses.warehouse_idWarehouse.
product_idintegerno PK products.product_idProduct.
on_handintegernoUnits physically recorded in stock at the end of the day (can be negative after posting errors).
allocatedintegernoUnits reserved for open customer orders. Available = on_hand − allocated.