feat(mfg-data-agent): 重构项目为制造业数据智能体
- 将项目从 lzwcai-mcpskills-analyzeOrder 重命名为 lzwcai-mcpskills-mfg-data-agent - 更新 README.md 中的项目描述,专注制造业数据分析与智能决策 - 修改配置文件和安装命令以匹配新项目名称 - 更新 MCP 服务器配置,使用新的命令名称 - 调整示例查询配置,从用户订单查询改为生产订单查询 - 更新依赖包和模块导入路径 - 修正项目描述和关键词,突出制造业数据智能体特性
This commit is contained in:
426
lzwcai_mcpskills_mfg_data_agent/指标趋势分析与拐点预警.sql
Normal file
426
lzwcai_mcpskills_mfg_data_agent/指标趋势分析与拐点预警.sql
Normal file
@@ -0,0 +1,426 @@
|
||||
-- =====================================================
|
||||
-- 指标趋势分析与拐点预警SQL
|
||||
-- Metric Trend Analysis and Turning Point Warning
|
||||
-- 数据库: PostgreSQL
|
||||
-- =====================================================
|
||||
|
||||
-- =====================================================
|
||||
-- 1. 日度指标基础数据
|
||||
-- =====================================================
|
||||
WITH daily_metrics AS (
|
||||
SELECT
|
||||
DATE(lr.event_time_utc::timestamp) AS metric_date,
|
||||
COUNT(DISTINCT lr.worker_name) AS worker_count,
|
||||
SUM(lr.duration_minutes) / 60.0 AS total_hours,
|
||||
SUM(lr.report_qty) AS total_output,
|
||||
CASE WHEN SUM(lr.duration_minutes) > 0
|
||||
THEN SUM(lr.report_qty) / (SUM(lr.duration_minutes) / 60.0)
|
||||
ELSE 0 END AS hourly_efficiency
|
||||
FROM fact_labor_report lr
|
||||
GROUP BY DATE(lr.event_time_utc::timestamp)
|
||||
),
|
||||
|
||||
daily_quality AS (
|
||||
SELECT
|
||||
DATE(qi.event_time_utc::timestamp) AS metric_date,
|
||||
SUM(qi.pass_qty) AS pass_qty,
|
||||
SUM(qi.fail_qty) AS fail_qty,
|
||||
CASE WHEN SUM(qi.pass_qty) + SUM(qi.fail_qty) > 0
|
||||
THEN SUM(qi.fail_qty) * 100.0 / (SUM(qi.pass_qty) + SUM(qi.fail_qty))
|
||||
ELSE 0 END AS defect_rate
|
||||
FROM fact_quality_inspection qi
|
||||
GROUP BY DATE(qi.event_time_utc::timestamp)
|
||||
),
|
||||
|
||||
daily_production AS (
|
||||
SELECT
|
||||
DATE(wo.event_time_utc::timestamp) AS metric_date,
|
||||
SUM(wo.planned_qty) AS planned_qty,
|
||||
SUM(wo.completed_qty) AS completed_qty,
|
||||
CASE WHEN SUM(wo.planned_qty) > 0
|
||||
THEN SUM(wo.completed_qty) * 100.0 / SUM(wo.planned_qty)
|
||||
ELSE 0 END AS completion_rate
|
||||
FROM fact_work_order wo
|
||||
GROUP BY DATE(wo.event_time_utc::timestamp)
|
||||
),
|
||||
|
||||
combined_daily AS (
|
||||
SELECT
|
||||
COALESCE(dm.metric_date, dq.metric_date, dp.metric_date) AS metric_date,
|
||||
COALESCE(dm.worker_count, 0) AS worker_count,
|
||||
COALESCE(dm.total_hours, 0) AS total_hours,
|
||||
COALESCE(dm.total_output, 0) AS total_output,
|
||||
COALESCE(dm.hourly_efficiency, 0) AS hourly_efficiency,
|
||||
COALESCE(dq.defect_rate, 0) AS defect_rate,
|
||||
COALESCE(dp.completion_rate, 0) AS completion_rate
|
||||
FROM daily_metrics dm
|
||||
FULL OUTER JOIN daily_quality dq ON dm.metric_date = dq.metric_date
|
||||
FULL OUTER JOIN daily_production dp ON dm.metric_date = dp.metric_date
|
||||
WHERE COALESCE(dm.metric_date, dq.metric_date, dp.metric_date) IS NOT NULL
|
||||
),
|
||||
|
||||
numbered_data AS (
|
||||
SELECT
|
||||
*,
|
||||
ROW_NUMBER() OVER (ORDER BY metric_date) AS day_seq
|
||||
FROM combined_daily
|
||||
),
|
||||
|
||||
-- =====================================================
|
||||
-- 2. 移动平均计算 (7日移动平均)
|
||||
-- =====================================================
|
||||
moving_avg_step1 AS (
|
||||
SELECT
|
||||
metric_date,
|
||||
day_seq,
|
||||
worker_count,
|
||||
total_output,
|
||||
hourly_efficiency,
|
||||
defect_rate,
|
||||
completion_rate,
|
||||
AVG(hourly_efficiency) OVER (ORDER BY metric_date ROWS BETWEEN 6 PRECEDING AND CURRENT ROW) AS ma7_efficiency,
|
||||
AVG(total_output) OVER (ORDER BY metric_date ROWS BETWEEN 6 PRECEDING AND CURRENT ROW) AS ma7_output,
|
||||
AVG(defect_rate) OVER (ORDER BY metric_date ROWS BETWEEN 6 PRECEDING AND CURRENT ROW) AS ma7_defect_rate,
|
||||
AVG(completion_rate) OVER (ORDER BY metric_date ROWS BETWEEN 6 PRECEDING AND CURRENT ROW) AS ma7_completion_rate,
|
||||
AVG(day_seq) OVER (ORDER BY metric_date ROWS BETWEEN 6 PRECEDING AND CURRENT ROW) AS avg_x
|
||||
FROM numbered_data
|
||||
),
|
||||
|
||||
moving_avg AS (
|
||||
SELECT
|
||||
*,
|
||||
LAG(ma7_efficiency, 1) OVER (ORDER BY metric_date) AS prev_ma7_efficiency,
|
||||
LAG(ma7_output, 1) OVER (ORDER BY metric_date) AS prev_ma7_output,
|
||||
LAG(ma7_defect_rate, 1) OVER (ORDER BY metric_date) AS prev_ma7_defect_rate
|
||||
FROM moving_avg_step1
|
||||
),
|
||||
|
||||
-- =====================================================
|
||||
-- 3. 简化的趋势斜率计算
|
||||
-- =====================================================
|
||||
slope_calc AS (
|
||||
SELECT
|
||||
*,
|
||||
(ma7_efficiency - LAG(ma7_efficiency, 3) OVER (ORDER BY metric_date)) / 3.0 AS slope_efficiency,
|
||||
(ma7_output - LAG(ma7_output, 3) OVER (ORDER BY metric_date)) / 3.0 AS slope_output,
|
||||
(ma7_defect_rate - LAG(ma7_defect_rate, 3) OVER (ORDER BY metric_date)) / 3.0 AS slope_defect
|
||||
FROM moving_avg
|
||||
),
|
||||
|
||||
-- =====================================================
|
||||
-- 4. 趋势判断与异常检测
|
||||
-- =====================================================
|
||||
trend_analysis AS (
|
||||
SELECT
|
||||
metric_date,
|
||||
hourly_efficiency,
|
||||
total_output,
|
||||
defect_rate,
|
||||
completion_rate,
|
||||
ROUND(ma7_efficiency, 2) AS ma7_efficiency,
|
||||
ROUND(ma7_output, 2) AS ma7_output,
|
||||
ROUND(ma7_defect_rate, 2) AS ma7_defect_rate,
|
||||
ROUND(COALESCE(slope_efficiency, 0), 4) AS slope_efficiency,
|
||||
ROUND(COALESCE(slope_output, 0), 4) AS slope_output,
|
||||
ROUND(COALESCE(slope_defect, 0), 4) AS slope_defect,
|
||||
prev_ma7_efficiency,
|
||||
prev_ma7_output,
|
||||
prev_ma7_defect_rate,
|
||||
|
||||
CASE
|
||||
WHEN COALESCE(slope_efficiency, 0) > 0.3 THEN 'RISING'
|
||||
WHEN COALESCE(slope_efficiency, 0) < -0.3 THEN 'FALLING'
|
||||
ELSE 'STABLE'
|
||||
END AS efficiency_trend,
|
||||
|
||||
CASE
|
||||
WHEN COALESCE(slope_output, 0) > 3 THEN 'RISING'
|
||||
WHEN COALESCE(slope_output, 0) < -3 THEN 'FALLING'
|
||||
ELSE 'STABLE'
|
||||
END AS output_trend,
|
||||
|
||||
CASE
|
||||
WHEN COALESCE(slope_defect, 0) > 0.3 THEN 'RISING'
|
||||
WHEN COALESCE(slope_defect, 0) < -0.3 THEN 'FALLING'
|
||||
ELSE 'STABLE'
|
||||
END AS defect_trend,
|
||||
|
||||
CASE
|
||||
WHEN ma7_efficiency > 0 AND ABS(hourly_efficiency - ma7_efficiency) > ma7_efficiency * 0.3 THEN 'ANOMALY'
|
||||
ELSE 'NORMAL'
|
||||
END AS efficiency_status,
|
||||
|
||||
CASE
|
||||
WHEN ma7_output > 0 AND ABS(total_output - ma7_output) > ma7_output * 0.3 THEN 'ANOMALY'
|
||||
ELSE 'NORMAL'
|
||||
END AS output_status,
|
||||
|
||||
CASE
|
||||
WHEN defect_rate > ma7_defect_rate * 1.5 AND defect_rate > 5 THEN 'ANOMALY'
|
||||
ELSE 'NORMAL'
|
||||
END AS defect_status
|
||||
|
||||
FROM slope_calc
|
||||
)
|
||||
|
||||
-- =====================================================
|
||||
-- 输出:日度趋势分析明细
|
||||
-- =====================================================
|
||||
SELECT
|
||||
metric_date,
|
||||
ROUND(hourly_efficiency, 2) AS hourly_output,
|
||||
ma7_efficiency AS efficiency_ma7,
|
||||
slope_efficiency,
|
||||
efficiency_trend,
|
||||
efficiency_status,
|
||||
CASE
|
||||
WHEN prev_ma7_efficiency IS NOT NULL
|
||||
AND ma7_efficiency > prev_ma7_efficiency AND slope_efficiency < 0 THEN 'TURNING_POINT'
|
||||
WHEN prev_ma7_efficiency IS NOT NULL
|
||||
AND ma7_efficiency < prev_ma7_efficiency AND slope_efficiency > 0 THEN 'TURNING_POINT'
|
||||
ELSE 'NONE'
|
||||
END AS efficiency_turning_point,
|
||||
ROUND(total_output, 0) AS daily_output,
|
||||
ma7_output AS output_ma7,
|
||||
slope_output,
|
||||
output_trend,
|
||||
output_status,
|
||||
CASE
|
||||
WHEN prev_ma7_output IS NOT NULL
|
||||
AND ma7_output > prev_ma7_output AND slope_output < 0 THEN 'TURNING_POINT'
|
||||
WHEN prev_ma7_output IS NOT NULL
|
||||
AND ma7_output < prev_ma7_output AND slope_output > 0 THEN 'TURNING_POINT'
|
||||
ELSE 'NONE'
|
||||
END AS output_turning_point,
|
||||
ROUND(defect_rate, 2) AS defect_rate,
|
||||
ma7_defect_rate AS defect_rate_ma7,
|
||||
slope_defect,
|
||||
defect_trend,
|
||||
defect_status,
|
||||
CASE
|
||||
WHEN prev_ma7_defect_rate IS NOT NULL
|
||||
AND ma7_defect_rate > prev_ma7_defect_rate AND slope_defect < 0 THEN 'TURNING_POINT'
|
||||
WHEN prev_ma7_defect_rate IS NOT NULL
|
||||
AND ma7_defect_rate < prev_ma7_defect_rate AND slope_defect > 0 THEN 'TURNING_POINT'
|
||||
ELSE 'NONE'
|
||||
END AS defect_turning_point
|
||||
FROM trend_analysis
|
||||
ORDER BY metric_date DESC;
|
||||
|
||||
|
||||
-- =====================================================
|
||||
-- 补充查询1:周度趋势汇总
|
||||
-- =====================================================
|
||||
WITH weekly_metrics AS (
|
||||
SELECT
|
||||
DATE_TRUNC('week', lr.event_time_utc::timestamp)::date AS week_start,
|
||||
COUNT(DISTINCT lr.worker_name) AS worker_count,
|
||||
SUM(lr.duration_minutes) / 60.0 AS total_hours,
|
||||
SUM(lr.report_qty) AS total_output,
|
||||
CASE WHEN SUM(lr.duration_minutes) > 0
|
||||
THEN SUM(lr.report_qty) / (SUM(lr.duration_minutes) / 60.0)
|
||||
ELSE 0 END AS hourly_efficiency
|
||||
FROM fact_labor_report lr
|
||||
GROUP BY DATE_TRUNC('week', lr.event_time_utc::timestamp)
|
||||
),
|
||||
weekly_quality AS (
|
||||
SELECT
|
||||
DATE_TRUNC('week', qi.event_time_utc::timestamp)::date AS week_start,
|
||||
SUM(qi.fail_qty) * 100.0 / NULLIF(SUM(qi.pass_qty) + SUM(qi.fail_qty), 0) AS defect_rate
|
||||
FROM fact_quality_inspection qi
|
||||
GROUP BY DATE_TRUNC('week', qi.event_time_utc::timestamp)
|
||||
),
|
||||
weekly_combined AS (
|
||||
SELECT
|
||||
wm.week_start,
|
||||
wm.worker_count,
|
||||
wm.total_hours,
|
||||
wm.total_output,
|
||||
wm.hourly_efficiency,
|
||||
COALESCE(wq.defect_rate, 0) AS defect_rate
|
||||
FROM weekly_metrics wm
|
||||
LEFT JOIN weekly_quality wq ON wm.week_start = wq.week_start
|
||||
),
|
||||
weekly_with_lag AS (
|
||||
SELECT
|
||||
*,
|
||||
LAG(hourly_efficiency, 1) OVER (ORDER BY week_start) AS prev_efficiency,
|
||||
LAG(total_output, 1) OVER (ORDER BY week_start) AS prev_output,
|
||||
LAG(defect_rate, 1) OVER (ORDER BY week_start) AS prev_defect_rate
|
||||
FROM weekly_combined
|
||||
)
|
||||
SELECT
|
||||
week_start,
|
||||
worker_count,
|
||||
ROUND(total_hours, 1) AS total_hours,
|
||||
ROUND(total_output, 0) AS total_output,
|
||||
ROUND(hourly_efficiency, 2) AS hourly_output,
|
||||
ROUND(defect_rate, 2) AS defect_rate,
|
||||
CASE
|
||||
WHEN prev_efficiency IS NULL THEN 'NONE'
|
||||
WHEN hourly_efficiency > prev_efficiency * 1.1 THEN 'RISING'
|
||||
WHEN hourly_efficiency < prev_efficiency * 0.9 THEN 'FALLING'
|
||||
ELSE 'STABLE'
|
||||
END AS efficiency_trend,
|
||||
CASE
|
||||
WHEN prev_output IS NULL THEN 'NONE'
|
||||
WHEN total_output > prev_output * 1.1 THEN 'RISING'
|
||||
WHEN total_output < prev_output * 0.9 THEN 'FALLING'
|
||||
ELSE 'STABLE'
|
||||
END AS output_trend,
|
||||
CASE
|
||||
WHEN prev_defect_rate IS NULL THEN 'NONE'
|
||||
WHEN defect_rate > prev_defect_rate * 1.2 THEN 'RISING'
|
||||
WHEN defect_rate < prev_defect_rate * 0.8 THEN 'FALLING'
|
||||
ELSE 'STABLE'
|
||||
END AS defect_trend,
|
||||
ROUND((hourly_efficiency - COALESCE(prev_efficiency, hourly_efficiency)) / NULLIF(prev_efficiency, 0) * 100, 1) AS efficiency_wow_pct
|
||||
FROM weekly_with_lag
|
||||
ORDER BY week_start DESC;
|
||||
|
||||
|
||||
-- =====================================================
|
||||
-- 补充查询2:指标趋势汇总报告
|
||||
-- =====================================================
|
||||
WITH
|
||||
recent_data AS (
|
||||
SELECT
|
||||
DATE(lr.event_time_utc::timestamp) AS metric_date,
|
||||
SUM(lr.report_qty) / NULLIF(SUM(lr.duration_minutes) / 60.0, 0) AS hourly_efficiency,
|
||||
SUM(lr.report_qty) AS total_output
|
||||
FROM fact_labor_report lr
|
||||
WHERE lr.event_time_utc::timestamp >= CURRENT_DATE - INTERVAL '14 days'
|
||||
GROUP BY DATE(lr.event_time_utc::timestamp)
|
||||
),
|
||||
recent_quality AS (
|
||||
SELECT
|
||||
DATE(qi.event_time_utc::timestamp) AS metric_date,
|
||||
SUM(qi.fail_qty) * 100.0 / NULLIF(SUM(qi.pass_qty) + SUM(qi.fail_qty), 0) AS defect_rate
|
||||
FROM fact_quality_inspection qi
|
||||
WHERE qi.event_time_utc::timestamp >= CURRENT_DATE - INTERVAL '14 days'
|
||||
GROUP BY DATE(qi.event_time_utc::timestamp)
|
||||
),
|
||||
period_stats AS (
|
||||
SELECT
|
||||
AVG(CASE WHEN rd.metric_date >= CURRENT_DATE - INTERVAL '7 days' THEN rd.hourly_efficiency END) AS avg_eff_7d,
|
||||
AVG(CASE WHEN rd.metric_date >= CURRENT_DATE - INTERVAL '7 days' THEN rd.total_output END) AS avg_output_7d,
|
||||
AVG(CASE WHEN rd.metric_date < CURRENT_DATE - INTERVAL '7 days' THEN rd.hourly_efficiency END) AS avg_eff_prev7d,
|
||||
AVG(CASE WHEN rd.metric_date < CURRENT_DATE - INTERVAL '7 days' THEN rd.total_output END) AS avg_output_prev7d
|
||||
FROM recent_data rd
|
||||
),
|
||||
quality_stats AS (
|
||||
SELECT
|
||||
AVG(CASE WHEN rq.metric_date >= CURRENT_DATE - INTERVAL '7 days' THEN rq.defect_rate END) AS avg_defect_7d,
|
||||
AVG(CASE WHEN rq.metric_date < CURRENT_DATE - INTERVAL '7 days' THEN rq.defect_rate END) AS avg_defect_prev7d
|
||||
FROM recent_quality rq
|
||||
)
|
||||
SELECT
|
||||
'efficiency_per_hour' AS metric_name,
|
||||
ROUND(ps.avg_eff_7d, 2) AS last_7d_avg,
|
||||
ROUND(ps.avg_eff_prev7d, 2) AS prev_7d_avg,
|
||||
ROUND((ps.avg_eff_7d - ps.avg_eff_prev7d) / NULLIF(ps.avg_eff_prev7d, 0) * 100, 1) AS change_rate_pct,
|
||||
CASE
|
||||
WHEN ps.avg_eff_7d > ps.avg_eff_prev7d * 1.05 THEN 'RISING'
|
||||
WHEN ps.avg_eff_7d < ps.avg_eff_prev7d * 0.95 THEN 'FALLING'
|
||||
ELSE 'STABLE'
|
||||
END AS trend,
|
||||
CASE
|
||||
WHEN ABS(ps.avg_eff_7d - ps.avg_eff_prev7d) / NULLIF(ps.avg_eff_prev7d, 0) > 0.2 THEN 'ANOMALY'
|
||||
ELSE 'NORMAL'
|
||||
END AS warning
|
||||
FROM period_stats ps
|
||||
|
||||
UNION ALL
|
||||
|
||||
SELECT
|
||||
'daily_output',
|
||||
ROUND(ps.avg_output_7d, 0),
|
||||
ROUND(ps.avg_output_prev7d, 0),
|
||||
ROUND((ps.avg_output_7d - ps.avg_output_prev7d) / NULLIF(ps.avg_output_prev7d, 0) * 100, 1),
|
||||
CASE
|
||||
WHEN ps.avg_output_7d > ps.avg_output_prev7d * 1.05 THEN 'RISING'
|
||||
WHEN ps.avg_output_7d < ps.avg_output_prev7d * 0.95 THEN 'FALLING'
|
||||
ELSE 'STABLE'
|
||||
END,
|
||||
CASE
|
||||
WHEN ABS(ps.avg_output_7d - ps.avg_output_prev7d) / NULLIF(ps.avg_output_prev7d, 0) > 0.2 THEN 'ANOMALY'
|
||||
ELSE 'NORMAL'
|
||||
END
|
||||
FROM period_stats ps
|
||||
|
||||
UNION ALL
|
||||
|
||||
SELECT
|
||||
'defect_rate_pct',
|
||||
ROUND(qs.avg_defect_7d, 2),
|
||||
ROUND(qs.avg_defect_prev7d, 2),
|
||||
ROUND((qs.avg_defect_7d - qs.avg_defect_prev7d) / NULLIF(qs.avg_defect_prev7d, 0) * 100, 1),
|
||||
CASE
|
||||
WHEN qs.avg_defect_7d > qs.avg_defect_prev7d * 1.1 THEN 'RISING'
|
||||
WHEN qs.avg_defect_7d < qs.avg_defect_prev7d * 0.9 THEN 'FALLING'
|
||||
ELSE 'STABLE'
|
||||
END,
|
||||
CASE
|
||||
WHEN qs.avg_defect_7d > 8 THEN 'THRESHOLD_EXCEEDED'
|
||||
WHEN qs.avg_defect_7d > qs.avg_defect_prev7d * 1.3 THEN 'ANOMALY_RISING'
|
||||
ELSE 'NORMAL'
|
||||
END
|
||||
FROM quality_stats qs;
|
||||
|
||||
|
||||
-- =====================================================
|
||||
-- 补充查询3:拐点预警汇总
|
||||
-- =====================================================
|
||||
WITH daily_eff AS (
|
||||
SELECT
|
||||
DATE(lr.event_time_utc::timestamp) AS metric_date,
|
||||
SUM(lr.report_qty) / NULLIF(SUM(lr.duration_minutes) / 60.0, 0) AS hourly_efficiency
|
||||
FROM fact_labor_report lr
|
||||
GROUP BY DATE(lr.event_time_utc::timestamp)
|
||||
),
|
||||
with_ma_step1 AS (
|
||||
SELECT
|
||||
metric_date,
|
||||
hourly_efficiency,
|
||||
AVG(hourly_efficiency) OVER (ORDER BY metric_date ROWS BETWEEN 6 PRECEDING AND CURRENT ROW) AS ma7
|
||||
FROM daily_eff
|
||||
),
|
||||
with_ma AS (
|
||||
SELECT
|
||||
metric_date,
|
||||
hourly_efficiency,
|
||||
ma7,
|
||||
LAG(ma7, 1) OVER (ORDER BY metric_date) AS prev_ma7,
|
||||
LAG(ma7, 2) OVER (ORDER BY metric_date) AS prev2_ma7
|
||||
FROM with_ma_step1
|
||||
),
|
||||
turning_points AS (
|
||||
SELECT
|
||||
metric_date,
|
||||
hourly_efficiency,
|
||||
ma7,
|
||||
prev_ma7,
|
||||
prev2_ma7,
|
||||
CASE
|
||||
WHEN prev2_ma7 IS NOT NULL
|
||||
AND prev_ma7 < prev2_ma7 AND ma7 > prev_ma7 THEN 'UPWARD'
|
||||
WHEN prev2_ma7 IS NOT NULL
|
||||
AND prev_ma7 > prev2_ma7 AND ma7 < prev_ma7 THEN 'DOWNWARD'
|
||||
ELSE NULL
|
||||
END AS turning_type
|
||||
FROM with_ma
|
||||
)
|
||||
SELECT
|
||||
metric_date,
|
||||
ROUND(hourly_efficiency, 2) AS daily_efficiency,
|
||||
ROUND(ma7, 2) AS ma7_line,
|
||||
turning_type,
|
||||
CASE
|
||||
WHEN turning_type = 'UPWARD' THEN 'MAINTAIN_CURRENT_MEASURES'
|
||||
WHEN turning_type = 'DOWNWARD' THEN 'INVESTIGATE_AND_IMPROVE'
|
||||
ELSE 'NONE'
|
||||
END AS recommendation
|
||||
FROM turning_points
|
||||
WHERE turning_type IS NOT NULL
|
||||
ORDER BY metric_date DESC
|
||||
LIMIT 10;
|
||||
Reference in New Issue
Block a user