Developer ToolsFree generatorPDF, Excel, Word exportFood and Beverage Manufacturing

Food Lot Traceability SQL Generator: One Step Forward, One Step Back

A mock recall is only as fast as your lot genealogy query. This generator produces forward and backward trace SQL for a genealogy table that records which input lots were consumed into which output lots.

Fill in

Table with one row per consumption of a lot into another lot

The ingredient or component lot that was consumed

The lot produced from it

Generated code
Download:

Backward trace: which ingredient lots went into this lot

WITH RECURSIVE back_trace AS (
  SELECT input_lot AS lot_no, output_lot AS used_in, qty_consumed AS qty, 1 AS depth
  FROM lot_genealogy
  WHERE output_lot = 'FG-240918-03'
  UNION ALL
  SELECT g.input_lot, g.output_lot, g.qty_consumed, b.depth + 1
  FROM lot_genealogy g
  JOIN back_trace b ON g.output_lot = b.lot_no
  WHERE b.depth < 10
)
SELECT lot_no, used_in, qty, depth
FROM back_trace
ORDER BY depth, lot_no;

Forward trace: where did this lot go

WITH RECURSIVE fwd_trace AS (
  SELECT output_lot AS lot_no, 1 AS depth
  FROM lot_genealogy
  WHERE input_lot = 'FG-240918-03'
  UNION ALL
  SELECT g.output_lot, f.depth + 1
  FROM lot_genealogy g
  JOIN fwd_trace f ON g.input_lot = f.lot_no
  WHERE f.depth < 10
)
SELECT DISTINCT s.customer_id, s.lot_no, s.ship_date
FROM shipment_lines s
WHERE s.lot_no = 'FG-240918-03'
   OR s.lot_no IN (SELECT lot_no FROM fwd_trace)
ORDER BY s.ship_date, s.customer_id;

Mock recall timing record

-- Start the clock when you run the queries, stop when the customer list is verified.
-- Record: lot traced = FG-240918-03, query run time, rows returned, reconciliation of produced vs shipped vs on hand.

Table and column names above are generic placeholders, not the schema of any specific ERP. Map them to your own genealogy and shipping tables. The WITH RECURSIVE form works in PostgreSQL, MySQL 8, SQLite and others; SQL Server uses WITH without the RECURSIVE keyword and Oracle accepts it from 11gR2. Test against a copy of the data and watch for circular lot references, which the depth limit guards against.

Run a trace against your ERP data

Optional session to map this query to your lot tables and test it on a copy of your data.

Optional. The tool and every export work without this. No spam.

How to use the generator

Enter the lot you want to trace and map the field names to your own tables. Copy the backward query to find every ingredient and packaging lot that went into a finished lot. Copy the forward query to find every downstream lot and every customer shipment that received it. Run both on a copy of production data, review the row counts, and save the output as evidence for your mock recall record.

  • Trace in both directions for every mock recall
  • Keep the depth limit as a guard against circular records
  • Reconcile produced, shipped, on hand and scrapped quantities

Why recursion is needed

A finished lot may consume a blend lot, which consumed a premix lot, which consumed a raw material lot. A single join finds only one level. A recursive common table expression walks the genealogy until no new lots appear, which is how you catch rework loops, carryover blends and multi-stage production.

Fit with FSMA 204 records

Food Traceability Rule records tie key data elements to critical tracking events such as receiving, transformation and shipping for foods on the Food Traceability List. The query here uses the genealogy link you already keep. Make sure your tables also store the traceability lot code, location and date for each event, and confirm which events and dates apply to you against the current FDA rule and its compliance date.

Common mistakes

Tracing only forward, missing rework that re-enters a lot, joining on lot number alone when lot numbers repeat across items or plants, and forgetting packaging and processing aid lots. In an ERP lot numbers often are unique only within an item, so add the item key to joins if your schema needs it.

Frequently Asked Questions

Does this work in every ERP?

It works on any relational schema once you map the table and column names. Different ERPs store lot genealogy in different tables, so treat the names as placeholders and verify with your data dictionary.

What is a recursive CTE?

A query that references itself to walk a hierarchy level by level. For lot trace it follows each lot to the lots it fed or was made from until nothing new is found.

Why is there a depth limit?

It stops runaway loops if bad data creates a circular reference, for example a lot recorded as consuming itself through rework. Raise it if your process truly has more stages.

Is this enough to meet FSMA 204?

No. It supports the trace step. The rule also requires specific key data elements per tracking event and the ability to provide an electronic sortable spreadsheet on request, so review the current rule text.

Netray can map this logic to your real lot tables in SyteLine, NetSuite, M3 or LN and run it read-only. The generator itself is free.