40-clients/ucepsa/edge-oee-demo/sql/071_loss_intelligence_dedupe.sql

66 lines
1.9 KiB
SQL

DROP VIEW IF EXISTS mv_reports_ucepsa_demo.loss_priority_board;
CREATE VIEW mv_reports_ucepsa_demo.loss_priority_board AS
WITH filtered AS (
SELECT e.*
FROM mv_reports_ucepsa_demo.loss_events_current e
WHERE NOT (
e.loss_type = 'STALE_OR_BAD_TELEMETRY'
AND EXISTS (
SELECT 1
FROM mv_reports_ucepsa_demo.loss_events_current x
WHERE x.machine_id = e.machine_id
AND x.loss_type = 'SIN_TELEMETRIA'
)
)
)
SELECT
row_number() OVER (
ORDER BY
(
severity_score
+ LEAST((COALESCE(cost_eur, 0) * 10), 50)::int
+ LEAST((COALESCE(duration_min, 0) * 2), 40)::int
) DESC,
detected_at DESC
) AS priority_rank,
(
severity_score
+ LEAST((COALESCE(cost_eur, 0) * 10), 50)::int
+ LEAST((COALESCE(duration_min, 0) * 2), 40)::int
) AS priority_score,
CASE
WHEN (
severity_score
+ LEAST((COALESCE(cost_eur, 0) * 10), 50)::int
+ LEAST((COALESCE(duration_min, 0) * 2), 40)::int
) >= 90 THEN 'CRÍTICA'
WHEN (
severity_score
+ LEAST((COALESCE(cost_eur, 0) * 10), 50)::int
+ LEAST((COALESCE(duration_min, 0) * 2), 40)::int
) >= 60 THEN 'ALTA'
WHEN (
severity_score
+ LEAST((COALESCE(cost_eur, 0) * 10), 50)::int
+ LEAST((COALESCE(duration_min, 0) * 2), 40)::int
) >= 35 THEN 'MEDIA'
ELSE 'BAJA'
END AS priority_level,
detected_at,
machine_id,
asset,
order_ref,
loss_type,
severity,
duration_min,
cost_eur,
status,
description,
recommended_action,
evidence_json
FROM filtered
ORDER BY priority_score DESC, detected_at DESC;
GRANT SELECT ON mv_reports_ucepsa_demo.loss_priority_board TO grafana_ucepsa_ro;