feat(mfg-data-agent): 重构项目为制造业数据智能体

- 将项目从 lzwcai-mcpskills-analyzeOrder 重命名为 lzwcai-mcpskills-mfg-data-agent
- 更新 README.md 中的项目描述,专注制造业数据分析与智能决策
- 修改配置文件和安装命令以匹配新项目名称
- 更新 MCP 服务器配置,使用新的命令名称
- 调整示例查询配置,从用户订单查询改为生产订单查询
- 更新依赖包和模块导入路径
- 修正项目描述和关键词,突出制造业数据智能体特性
This commit is contained in:
2026-01-08 00:36:43 +08:00
parent 2d2db5e866
commit 679f2d2d5d
30 changed files with 31 additions and 31 deletions

View 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;