Inventory velocity rolled up from the per-lot `mart_inventory_health` to (inv_month × site × temp_class × client_segment). `inv_month` is `toStartOfMonth(received_date)`. `turnover_ratio` is the average per-lot turnover (units_out_window / avg_qty_on_hand); `days_of_cover` is the average per-lot days of cover; `utilization_pct` is site utilization (occupied ÷ capacity) joined from `mart_site_performance` at the region-level `site` grain — it is SITE-WIDE, not client-specific. All three are `avg()` measures declared Nullable(Float64) (ClickHouse avg-of-Nullable semantics); `avg()` ignores NULLs, so NULL-velocity (dead / new) lots are skipped by construction — do not zero-fill them. The `site` dimension is REGION-LEVEL. De-identified — no lot_id, no client_id.
- mediumAveraging avg-of-avg across mixed temp classes
Frozen / chilled / ambient turnover differs structurally. Slice by `temp_class` first; a single blended average across temp classes is an avg-of-averages that hides the mix.
- mediumReading utilization as client-specific
`utilization_pct` is SITE-WIDE (occupied ÷ capacity across all tenants stored at the site), joined at the region level. It is not attributable to one client's stock.
- lowZero-filling NULL turnover / days_of_cover
`avg()` ignores NULLs, so lots with no outbound velocity (dead / new stock) are skipped by construction — this is correct. Do not zero-fill NULL turnover / days_of_cover; a NULL means "velocity undefined", not "zero turns".
- “What is inventory turnover by temp class this year?”
- “Which regions carry the most days of cover for frozen stock?”
- “How does turnover compare across segments?”
- fulfillment
Turnover measures how fast stock moves; `fulfillment` measures how well orders ship. Pair to read stock velocity against service level for the same region / segment.