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
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.
Related Tools
Metal Detector Challenge Test Log Template
Document the start-up, hourly and end-of-shift checks of a metal detector with test pieces, reject confirmation and corrective action.
Costing & FinanceNet Content Overfill and Giveaway Cost Calculator
Find what your target weight and variation cost each year, and how much you save by lowering the mean fill.
Quality & InspectionFood Plant GMP Internal Audit Checklist (21 CFR 117 Subpart B)
Walk-through GMP checklist for food plants covering personnel, premises, equipment, sanitation, processes and storage.
Industry TemplatesMajor Food Allergens Reference: US, EU and Canada
Compare which allergens are regulated in the US, EU and Canada, with the ingredients where each one tends to hide.
More Developer Tools tools
See all- SAP Sales Order ABAP SELECT Generator (VBAK, VBAP, VBFA)
- SAP Sales Order Create BAPI ABAP Generator (BAPI_SALESORDER_CREATEFROMDAT2)
- SAP ABAP Open Items SELECT Generator
- SAP ACDOCA SQL Query Generator
- SAP QM Inspection Lot ABAP SELECT Generator
- SAP Quality Notification Pareto SQL Query Generator
- SAP QM Usage Decision BAPI Skeleton
- ABAP Custom Exception Class Generator
- ABAP Unit Test Class Generator