Five Analytics Use Cases: Reliability, Cost, Inventory, Backlog, and PM Compliance on the Gold Layer

🎯 Who this is for: Reliability and maintenance leaders who want to know exactly what a Databricks gold table can answer that their current Cognos report can't, data engineers who built Part 3's silver and gold tables and need the next layer of worked SQL, and BI developers connecting Databricks SQL to a Power BI or Tableau front end for a maintenance dashboard.

Series: Part 4 of 6 — MAS 9 + Databricks: Building the Maximo Data Lakehouse | Read time: 17 minutes

📖 The Gold Layer Was the Point

Part 3 of this series built silver.work_orders_enriched, silver.dim_asset, silver.inventory_demand, and silver.pm_effectiveness — the conformed, joined, meter-aware tables that turn raw Maximo extracts into something a business question can actually be asked against. It closed with two starter gold tables, gold.maintenance_cost_kpis and gold.asset_reliability_kpis, and a promise: five concrete use cases, each answering one named question a maintenance leader already asks in a monthly review, built on that same silver foundation.

This post keeps that promise. Every use case below is deliberately narrow — one gold table, one question, one piece of worked SQL — because Part 3 already made the case against a single sprawling "everything" gold table. None of these five use cases requires a new extraction pattern or a new silver join; they are all read from the tables that already exist. What's new here is the analytical layer on top: window functions for trend health instead of single-snapshot numbers, classification logic for inventory, aging buckets for backlog, and compliance-rate math for PM programs — the kind of query a Cognos report against the raw Maximo database struggles to express cleanly, but a Databricks SQL warehouse handles as an ordinary SELECT.

💡 Key insight: None of these five gold tables is impressive because of what it computes — MTBF, a cost rollup, an ABC classification, a backlog bucket, and a compliance percentage are not exotic math. They're valuable because they're built once, on conformed silver tables, and then trusted by every dashboard and every closed-loop alert that reads them. The value is architectural, not algorithmic.

📊 Use Case 1 — Reliability Trend Health, Not Just This Quarter's Number

The MAS-RELIABILITY series defines the three numbers that matter — MTBF (operating time ÷ failures), MTTR (repair time ÷ repairs), and availability (MTBF ÷ (MTBF + MTTR)) — and is explicit that a single snapshot value invites the wrong kind of management: "managing to improve MTBF" as a static target instead of watching whether it's actually trending up or down for a specific asset class. gold.asset_reliability_kpis from Part 3 already computes MTBF and MTTR per asset class, per site, per quarter. What it doesn't yet answer is the question a reliability engineer actually needs: is this asset class's reliability improving, holding steady, or quietly degrading over the last year?

That's a trailing moving average, and it's exactly what Databricks SQL window functions are built for — computing a value across a frame of rows relative to the current one, without a self-join or a Python loop.

CREATE OR REPLACE TABLE gold.reliability_trend_health AS
SELECT
  asset_class,
  siteid,
  reliability_quarter,
  failure_count,
  mtbf_days,
  mttr_hours,
  -- Trailing 4-quarter moving average — the trend, not the snapshot
  ROUND(AVG(mtbf_days) OVER (
    PARTITION BY asset_class, siteid
    ORDER BY reliability_quarter
    ROWS BETWEEN 3 PRECEDING AND CURRENT ROW
  ), 1) AS mtbf_trailing_4q_avg,
  ROUND(AVG(mttr_hours) OVER (
    PARTITION BY asset_class, siteid
    ORDER BY reliability_quarter
    ROWS BETWEEN 3 PRECEDING AND CURRENT ROW
  ), 2) AS mttr_trailing_4q_avg,
  -- Flag degradation: this quarter's MTBF meaningfully below its own trailing trend
  CASE
    WHEN mtbf_days < 0.85 * AVG(mtbf_days) OVER (
      PARTITION BY asset_class, siteid
      ORDER BY reliability_quarter
      ROWS BETWEEN 4 PRECEDING AND 1 PRECEDING
    ) THEN 'DEGRADING'
    ELSE 'STABLE_OR_IMPROVING'
  END AS trend_flag
FROM gold.asset_reliability_kpis;

The 15% threshold in that CASE expression — this quarter's MTBF falling more than 15% below the prior four quarters' average, deliberately excluding the current quarter from its own comparison baseline — isn't a universal constant; it's a starting point to tune against your own asset classes' historical volatility. What matters structurally is the pattern: compare the current period against a trailing window that excludes itself, so a single bad quarter shows up as a flag rather than quietly pulling its own baseline down with it. A pump asset class sitting at DEGRADING for two consecutive quarters is a different conversation than one bad month — it's a signal that a PM interval, a spare-parts quality issue, or an operating-condition change is worth investigating, tied directly back to the PM-effectiveness silver table from Part 3.

Reliability signalWhat it tells youWhere it comes from
MTBF trailing 4Q averageWhether failures are getting rarer or more frequent for this asset class, not just this quarter's countgold.asset_reliability_kpis, windowed
MTTR trailing 4Q averageWhether repairs are taking longer — a storeroom, permit, or skills problem, not a reliability oneSame table, same window
DEGRADING flagA concrete trigger for a reliability review, not a chart someone has to noticeThreshold comparison against the trailing window
💡 Key insight: A single quarter's MTBF is a fact. Four quarters of MTBF, windowed against each other, is a signal. The difference between a Cognos report and this gold table isn't the underlying numbers — it's that the window function turns a series of facts into a trend an engineer can act on without eyeballing a chart and guessing.

💰 Use Case 2 — Maintenance Cost Rollups With Month-Over-Month Variance

gold.maintenance_cost_kpis from Part 3 already rolls up total cost, work order count, and average cost per work order by site, asset class, and month. The gap it leaves is the one every budget review actually asks: is this month's cost in line with what we expected, or is it running hot? Maximo's own KPI List portlet has answered a version of this question inside Manage for years — it displays Actual, Target, and Variance for a KPI, then colors the row green (safe), yellow (caution), or red (past the alert threshold), with a trend indicator showing whether the color is moving the right direction since the last reading. The gold-layer version of that same idea, computed with a window function instead of a manually configured portlet threshold, looks like this:

CREATE OR REPLACE TABLE gold.cost_variance_kpis AS
SELECT
  siteid,
  asset_class,
  cost_month,
  total_cost,
  work_order_count,
  avg_cost_per_wo,
  -- Prior month's cost, via a window offset instead of a self-join
  LAG(total_cost) OVER (
    PARTITION BY siteid, asset_class ORDER BY cost_month
  ) AS prior_month_cost,
  ROUND(
    100.0 * (total_cost - LAG(total_cost) OVER (
      PARTITION BY siteid, asset_class ORDER BY cost_month
    )) / NULLIF(LAG(total_cost) OVER (
      PARTITION BY siteid, asset_class ORDER BY cost_month
    ), 0),
    1
  ) AS mom_variance_pct,
  -- Band the variance the way the KPI List portlet colors Actual vs. Target vs. Variance
  CASE
    WHEN ABS(100.0 * (total_cost - LAG(total_cost) OVER (
      PARTITION BY siteid, asset_class ORDER BY cost_month
    )) / NULLIF(LAG(total_cost) OVER (
      PARTITION BY siteid, asset_class ORDER BY cost_month
    ), 0)) <= 10 THEN 'GREEN'
    WHEN ABS(100.0 * (total_cost - LAG(total_cost) OVER (
      PARTITION BY siteid, asset_class ORDER BY cost_month
    )) / NULLIF(LAG(total_cost) OVER (
      PARTITION BY siteid, asset_class ORDER BY cost_month
    ), 0)) <= 25 THEN 'YELLOW'
    ELSE 'RED'
  END AS variance_band
FROM gold.maintenance_cost_kpis;

LAG() is doing the same job here that a self-join against the prior month would do in a database without native window function support, and it's worth naming why the window version is the better choice beyond brevity: a self-join re-scans and re-joins the table, while a single windowed pass computes every row's comparison in one sequential sweep, which matters once this table is running against several years of monthly history across every site and asset class combination. Databricks' own 2026 guidance for its AI/BI metric views goes a step further, adding a built-in offset field specifically for period-over-period measures like this — the same pattern this hand-written LAG() expresses explicitly, available as a declared measure property for teams building on metric views instead of raw SQL.

Variance bandThresholdKPI List analogAction
GREEN≤10% month-over-month swingActual within Target's safe zoneNo action — normal cost variation
YELLOW10–25% swingBetween caution and alert valueReview at the next monthly cost meeting
RED>25% swingPast the alert valueInvestigate immediately — often a single large work order or a parts price spike

Tune the 10%/25% bands to your own site's historical cost volatility rather than copying them verbatim — a site with genuinely lumpy capital-adjacent maintenance work (a scheduled major overhaul landing in one month) will trip a naive threshold every time that overhaul cycle recurs, and a threshold that fires on a known, planned pattern trains people to ignore the alert. Where that's a real pattern, exclude planned major work orders from this specific rollup and roll them up separately — the same "match the cleansing effort to what the table needs" principle Part 3 applied to silver joins applies here to gold-layer thresholds too.

📦 Use Case 3 — Slow-Moving and Excess Inventory, ABC Crossed With XYZ

silver.inventory_demand from Part 3 already joins material-use transactions against inventory balances and purchase-order receipts. The Databricks Solution described in the source roadmap for this series names "obsolescence prediction — which parts are trending toward zero demand" as a use case Databricks enables beyond IBM's MRO Inventory Optimization SaaS product, and the classic technique for finding those parts — before reaching for a full ML obsolescence model — is a two-way classification most inventory teams already know by name but rarely implement consistently: ABC by consumption value, XYZ by demand variability.

ABC buckets parts by their share of annual consumption value using the Pareto principle — a small number of A-items typically account for roughly 80% of spend, B-items the next tier, and a long tail of C-items contributing very little individually. XYZ buckets the same parts by how predictable their demand is — X-items consume at a steady, forecastable rate, Y-items show moderate seasonal or lumpy variation, and Z-items are sporadic or one-off. Crossing the two tells you something neither axis tells you alone: an AZ part (high value, unpredictable demand) needs the most attention and the largest safety buffer, while a CX part (low value, steady demand) can run on a simple reorder point with minimal oversight.

CREATE OR REPLACE TABLE gold.inventory_classification AS
WITH item_stats AS (
  SELECT
    itemnum,
    siteid,
    SUM(annual_usage_qty * unit_cost) AS annual_consumption_value,
    AVG(monthly_usage_qty) AS avg_monthly_usage,
    STDDEV(monthly_usage_qty) AS stddev_monthly_usage,
    MAX(last_issue_date) AS last_issue_date,
    current_qoh
  FROM silver.inventory_demand
  GROUP BY itemnum, siteid, current_qoh
),
ranked AS (
  SELECT *,
    SUM(annual_consumption_value) OVER (
      PARTITION BY siteid ORDER BY annual_consumption_value DESC
    ) / SUM(annual_consumption_value) OVER (PARTITION BY siteid) AS cumulative_value_pct,
    stddev_monthly_usage / NULLIF(avg_monthly_usage, 0) AS coeff_of_variation
  FROM item_stats
)
SELECT
  itemnum, siteid, annual_consumption_value, current_qoh, last_issue_date,
  CASE
    WHEN cumulative_value_pct <= 0.80 THEN 'A'
    WHEN cumulative_value_pct <= 0.95 THEN 'B'
    ELSE 'C'
  END AS abc_class,
  CASE
    WHEN coeff_of_variation <= 0.5 THEN 'X'
    WHEN coeff_of_variation <= 1.0 THEN 'Y'
    ELSE 'Z'
  END AS xyz_class,
  -- Slow-moving / excess flag: on-hand stock, zero issues in 12 months
  CASE
    WHEN current_qoh > 0 AND DATEDIFF(CURRENT_DATE(), last_issue_date) > 365
    THEN TRUE ELSE FALSE
  END AS is_slow_moving_candidate
FROM ranked;
ClassValue tier (ABC)Demand pattern (XYZ)Typical action
AXTop ~80% of spendStable, forecastableTight reorder point, min-max well-tuned, low safety stock needed
AZTop ~80% of spendSporadic, unpredictableHighest attention — largest safety buffer, candidate for vendor-managed inventory or consignment
CXLong tail of spendStableSimple reorder point, minimal review cadence
CZ / slow-moving flagLong tail of spendSporadic or deadObsolescence review candidate — cross-site transfer or disposal before reordering

The is_slow_moving_candidate flag deliberately uses a blunt rule — stock on hand, no issue transaction in the trailing 365 days — because it's meant as a screening filter for a human review, not an automated disposal trigger. A part with zero issues in a year might be a genuinely dead SKU, or it might be a critical spare for a low-frequency, high-consequence failure mode that hasn't happened yet — the same distinction MAS-RELIABILITY's Part 2 makes about censored data biasing an MTBF estimate downward. Cross this flag against silver.dim_asset's criticality rating before recommending disposal; a CZ-classified spare tied to a criticality-1 asset is not the same disposal decision as a CZ part with no active asset link at all.

🗂️ Use Case 4 — Work Order Backlog Aging by Craft

Backlog is the metric most maintenance teams already track informally — "we're behind on PM's" or "the electricians are swamped" — but rarely measure with the precision that turns it into a scheduling decision instead of a vibe. The discipline that matters, and that most naive backlog queries get wrong, is scoping the count correctly: backlog should be ready-to-schedule work only — approved, no outstanding parts or permit block — not every open work order regardless of status. Maximo's own Work Queues concept, including the dedicated Safety Critical Backlog queue inside the Manage work-queue portlets, already draws this line inside the application; the gold-layer version needs to draw it the same way or the resulting weeks-of-backlog number overstates real scheduling pressure.

CREATE OR REPLACE TABLE gold.backlog_aging AS
WITH ready_backlog AS (
  SELECT
    wo.wonum,
    wo.siteid,
    craft.craft_code,
    wo.status,
    est.estlabhrs,
    DATEDIFF(CURRENT_DATE(), wo.changedate) AS days_in_backlog
  FROM bronze.maximo_workorder_raw wo
  JOIN silver.wo_labor_craft craft ON wo.wonum = craft.wonum
  JOIN silver.wo_estimates est ON wo.wonum = est.wonum
  WHERE wo.status IN ('APPR', 'WSCH')      -- approved and ready, not blocked
    AND wo.status NOT IN ('WMATL', 'WAPPR') -- explicitly exclude parts/approval-blocked work
),
craft_capacity AS (
  SELECT craft_code, siteid, weekly_capacity_hrs FROM silver.dim_craft
)
SELECT
  rb.siteid,
  rb.craft_code,
  SUM(rb.estlabhrs) AS total_ready_backlog_hrs,
  ROUND(SUM(rb.estlabhrs) / NULLIF(cc.weekly_capacity_hrs, 0), 1) AS weeks_of_backlog,
  SUM(CASE WHEN rb.days_in_backlog <= 14 THEN rb.estlabhrs ELSE 0 END) AS hrs_0_2_weeks,
  SUM(CASE WHEN rb.days_in_backlog BETWEEN 15 AND 28 THEN rb.estlabhrs ELSE 0 END) AS hrs_2_4_weeks,
  SUM(CASE WHEN rb.days_in_backlog BETWEEN 29 AND 42 THEN rb.estlabhrs ELSE 0 END) AS hrs_4_6_weeks,
  SUM(CASE WHEN rb.days_in_backlog > 42 THEN rb.estlabhrs ELSE 0 END) AS hrs_over_6_weeks
FROM ready_backlog rb
JOIN craft_capacity cc ON rb.craft_code = cc.craft_code AND rb.siteid = cc.siteid
GROUP BY rb.siteid, rb.craft_code, cc.weekly_capacity_hrs;
Weeks of ready backlogInterpretationTypical response
3–5 weeksHealthy — enough queued work to schedule efficiently without idle crewsNo action; this is the target range most published maintenance benchmarks treat as normal
6+ weeksAging — work is piling up faster than the craft can execute it, and equipment risk accumulates the longer it waitsEscalate: overtime, contractor support, or a look at whether PM frequency is generating more corrective work than the crew can absorb
Under 2–3 weeksStarved — a craft with too little queued work is itself a planning problem, not a successCheck whether planning/scheduling is falling behind on approving and estimating new work

The hrs_over_6_weeks bucket deserves specific attention beyond the total, because industry deferred-maintenance research puts a real number on why aging backlog compounds rather than just sitting still: unaddressed deferred maintenance tends to compound at roughly 7% annually as components that would have been a simple repair degrade into more extensive failures. A backlog table that only reports a total weeks-of-backlog number hides which portion of that backlog is six-plus weeks old and actively compounding versus which portion is two weeks old and perfectly normal queue depth — the bucket breakdown is what turns "we have 8 weeks of backlog" into "we have 8 weeks of backlog, but 5 of those weeks are less than two weeks old and only 1 week's worth is aging past six weeks," which is a very different planning conversation.

💡 Key insight: A single weeks-of-backlog number tempts a planner into treating 8 weeks of freshly-approved, well-understood work the same as 8 weeks that includes aging, at-risk work orders. Bucket it by age, not just by total, or the metric hides exactly the signal — compounding risk on old work — it exists to surface.

✅ Use Case 5 — PM Compliance Rate

PM compliance answers a narrower and more specific question than "are we doing our PMs": of the preventive maintenance work scheduled to be completed in a given period, what percentage was actually completed within its compliance window — not just completed eventually, but completed close enough to its due date that the PM is doing the job it's scheduled to do. Published maintenance benchmarks treat roughly 85% as the practical floor: PM compliance is widely regarded as one of the most predictive leading indicators of future reliability, and reactive failure rates tend to climb sharply once compliance drops meaningfully below that threshold.

CREATE OR REPLACE TABLE gold.pm_compliance_kpis AS
WITH pm_due AS (
  SELECT
    pm.pmnum,
    pm.assetnum,
    a.assettype AS asset_class,
    pm.siteid,
    pm.frequency,
    pm.duedate,
    pm.actual_completion_date,
    -- Compliance window: completed within 10% of frequency, before or after due date
    DATEDIFF(pm.actual_completion_date, pm.duedate) AS days_variance,
    (pm.frequency * 0.10) AS allowed_variance_days
  FROM bronze.maximo_pm_raw pm
  JOIN silver.dim_asset a ON pm.assetnum = a.assetnum AND a.__is_current = true
  WHERE pm.duedate BETWEEN DATE_TRUNC('month', CURRENT_DATE()) - INTERVAL 3 MONTH
    AND CURRENT_DATE()
)
SELECT
  asset_class,
  siteid,
  DATE_TRUNC('month', duedate) AS due_month,
  COUNT(*) AS pms_due,
  SUM(CASE
    WHEN actual_completion_date IS NOT NULL
      AND ABS(days_variance) <= allowed_variance_days
    THEN 1 ELSE 0
  END) AS pms_compliant,
  ROUND(100.0 * SUM(CASE
    WHEN actual_completion_date IS NOT NULL
      AND ABS(days_variance) <= allowed_variance_days
    THEN 1 ELSE 0
  END) / NULLIF(COUNT(*), 0), 1) AS compliance_pct,
  CASE
    WHEN 100.0 * SUM(CASE
      WHEN actual_completion_date IS NOT NULL AND ABS(days_variance) <= allowed_variance_days
      THEN 1 ELSE 0 END) / NULLIF(COUNT(*), 0) >= 85 THEN 'ON_TARGET'
    ELSE 'BELOW_THRESHOLD'
  END AS compliance_flag
FROM pm_due
GROUP BY asset_class, siteid, DATE_TRUNC('month', duedate);

The allowed_variance_days expression — 10% of the PM's own frequency — matters more than it looks, because a fixed variance window (say, "within 5 days") treats a weekly PM and an annual PM identically, and they shouldn't be. A weekly PM completed 5 days late has essentially skipped a whole cycle; an annual PM completed 5 days late is well within normal scheduling noise. Scaling the allowed variance to the PM's own frequency is what makes the compliance percentage comparable across a fleet that mixes short-interval and long-interval PM tasks, the same way Part 3's PM-effectiveness silver table joined against a 90-day lookback window scoped to the question being asked rather than a single fixed number applied everywhere.

Compliance levelSignalTypical response
≥95%Strong program disciplineMaintain; consider whether some low-value PMs are candidates for frequency reduction
85–95%Acceptable, watch for driftMonthly trend review; check whether any single asset class is dragging the average down
<85%Below the threshold most benchmarks associate with rising reactive failure ratesEscalate — planning capacity, parts availability, or crew staffing is the usual root cause, not PM design itself

🔔 Closing the Loop — From Gold Table to Maximo Action

Every use case above produces a table a BI tool can read directly — connect Power BI or Tableau to a Databricks SQL warehouse endpoint and each of these five gold tables becomes a dashboard tile with almost no additional modeling work, because the aggregation and business logic are already applied. That's the payoff of gold-layer design done right, and it's a legitimate stopping point for a first build. But this series' index post names the pattern that actually changes behavior, not just visibility: closed-loop — a threshold breach in one of these tables should trigger an action back inside Maximo, not just a color change on a chart someone has to remember to check.

Databricks SQL Alerts, generally available as of 2026, are built for exactly this: a scheduled query against any of these gold tables, evaluated on a cadence, that fires a notification — or, via a webhook action, an HTTP call — the moment a condition is met. Pointed at gold.backlog_aging for weeks_of_backlog > 6, or at gold.pm_compliance_kpis for compliance_flag = 'BELOW_THRESHOLD', or at gold.reliability_trend_health for trend_flag = 'DEGRADING', the alert becomes the mechanism that calls Maximo's REST API to create a service request, bump a work order's priority, or add an asset to a Health work queue — the same closed-loop shape MAS 9.1's own Operational Dashboard KPI Value cards use natively when they link a KPI directly to a Maximo work queue, except extended past Maximo's own data to whatever the Databricks gold layer can see.

Trigger conditionGold tableMaximo-side action
trend_flag = 'DEGRADING' for 2+ consecutive quartersgold.reliability_trend_healthCreate a reliability-review service request; flag the asset class in Maximo Health
variance_band = 'RED'gold.cost_variance_kpisNotify the site maintenance supervisor; flag for the monthly cost review
is_slow_moving_candidate = TRUE with high criticalitygold.inventory_classificationRoute to a storeroom review queue rather than auto-reorder
weeks_of_backlog > 6gold.backlog_agingCreate an overtime/contractor-support request for that craft
compliance_flag = 'BELOW_THRESHOLD' for 2+ monthsgold.pm_compliance_kpisEscalate to planning/scheduling; audit crew capacity against PM plan volume
💡 Key insight: A dashboard is where a human interprets a trend. An alert is where the platform acts on a threshold without waiting for a human to notice. Build both — the dashboard for root-cause investigation, the alert for the cases where waiting for someone to check a chart is itself the risk.

⚠️ Common Mistakes Building These Five Use Cases

  • Reporting a snapshot instead of a trend for reliability and cost. A single quarter's MTBF or a single month's cost tells you where you are, not where you're headed — window functions computing a trailing average are what turn a fact into a signal worth acting on.
  • Classifying inventory by value alone, skipping demand variability. ABC without XYZ tells you what's expensive; it doesn't tell you which expensive parts also need a larger safety buffer because their demand can't be forecast tightly.
  • Counting every open work order as backlog. Work blocked on parts, permits, or approvals isn't ready-to-schedule work — including it inflates weeks-of-backlog and points a planning conversation at the wrong root cause.
  • Using a fixed variance window for PM compliance across mixed frequencies. A flat "within 5 days" rule treats a weekly PM and an annual PM as equally tolerant of delay, when they aren't — scale the allowed variance to the PM's own frequency.
  • Building the gold table and stopping at the dashboard. A chart nobody checks regularly doesn't change behavior — pair each threshold with a Databricks SQL Alert that calls back into Maximo, or the gold layer never earns back the effort it took to build.
  • Copying threshold numbers verbatim instead of tuning them. The 85% PM compliance floor, the 6-week backlog-aging line, and the 10%/25% cost-variance bands in this post are industry starting points, not universal constants — validate them against your own site's historical volatility before wiring them to an automated alert.

🔧 Practical Notes Before Part 5

  • Build the reliability and cost use cases first. They read directly from Part 3's existing gold tables with no new silver joins required, making them the fastest of the five to stand up and validate against a Cognos number you already trust.
  • Get one craft's backlog aging right before rolling out fleet-wide. silver.dim_craft's weekly capacity figure has to be genuinely accurate for the weeks-of-backlog math to mean anything — a capacity number that's stale or aspirational produces a backlog metric nobody trusts.
  • Treat PM compliance threshold breaches as a planning conversation, not a technician performance metric. Compliance below 85% is almost always a capacity, parts, or scheduling problem — treating it as an individual accountability issue misses the actual lever.
  • Scope your first Databricks SQL Alert narrowly. Pick the one use case where a delayed human notice actually costs money or safety margin — backlog aging past 6 weeks on a safety-critical craft is a reasonable first alert to wire end-to-end before automating all five.
  • Part 5 picks up where these use cases hit a wall. All five here are descriptive and rule-based — a threshold, a window function, a classification. When a use case needs a genuine prediction instead of a rule (which asset will actually fail, which part will actually go obsolete), that's the custom-ML-versus-Maximo-Predict decision Part 5 works through.

Key Takeaways

  1. All five use cases read from Part 3's existing silver and gold tables — no new extraction pattern or silver join is required, which is the payoff of building the conformed dimensions and enriched work-order table correctly the first time.
  2. Reliability and cost need trend analysis, not snapshots — Databricks SQL window functions turn "this quarter's MTBF" into "is this asset class degrading," which is the question that actually drives a reliability decision.
  3. Inventory classification needs both value (ABC) and demand variability (XYZ) — crossing the two identifies which expensive parts also carry unpredictable demand and need the largest safety buffer, not just the closest watch.
  4. Backlog aging must be scoped to ready-to-schedule work and bucketed by age, not counted as every open work order — a single weeks-of-backlog number hides the compounding risk sitting in the six-plus-week bucket specifically.
  5. PM compliance below roughly 85%, and any threshold breach across these five gold tables, is worth wiring to a Databricks SQL Alert that closes the loop back into a Maximo work order or service request — a dashboard nobody checks doesn't change behavior; an alert that calls the REST API does.

References

Series Navigation

Previous:Part 3 — Building the Asset Lakehouse
Next:Part 5 — Custom ML vs. Maximo Predict

About TheMaximoGuys: We help Maximo developers and teams navigate the move to MAS 9 with practical, no-hype guidance grounded in how the platform actually behaves.

Published by TheMaximoGuys | July 2026