Files
lzwcai-mcp-server-package/lzwcai_mcpskills_mfg_data_agent/sql/工单执行进度与异常节点.sql
yuanzhipeng 3ea772c3be feat(mfg-data-agent): 添加HTML可视化仪表盘和优化项目配置
- 新增6个HTML可视化仪表盘组件用于数据展示
* 人效产值损耗三维模型仪表盘
* 指标趋势分析与拐点预警仪表盘
* 一页式决策简报仪表盘
* 订单延迟预警分析仪表盘
* 供应链风险预警仪表盘
* 工单执行进度与异常节点仪表盘
- 添加VSCode工作区配置文件
- 更新businessQueries.json业务查询配置
- 优化api_client.py API客户端实现
- 更新pyproject.toml项目依赖版本
- 重组SQL查询文件结构
- 删除v2版本冗余文档配置
- 添加v2版本技能清单文档
- 更新日志文件记录
2026-01-14 11:56:43 +08:00

410 lines
14 KiB
SQL
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
-- =====================================================
-- 工单执行进度与异常节点SQL
-- 数据库: PostgreSQL
-- 实时拉取工单数据,动态映射订单各环节状态
-- =====================================================
-- =====================================================
-- 1. 工单执行进度主视图
-- =====================================================
WITH work_order_base AS (
SELECT
wo.work_order_id,
wo.work_order_number,
wo.product_id,
wo.status,
wo.planned_qty,
wo.completed_qty,
wo.event_time_utc::timestamp AS start_time,
wo.last_updated_utc::timestamp AS last_update,
wo.source_system
FROM fact_work_order wo
),
product_info AS (
SELECT
product_id,
product_name,
product_category
FROM dim_product
WHERE is_current = 't'
),
labor_summary AS (
SELECT
work_order_number,
COUNT(DISTINCT worker_name) AS worker_count,
SUM(report_qty) AS total_report_qty,
SUM(duration_minutes) AS total_minutes,
MAX(event_time_utc::timestamp) AS last_report_time
FROM fact_labor_report
GROUP BY work_order_number
),
quality_summary AS (
SELECT
work_order_number,
SUM(pass_qty) AS pass_qty,
SUM(fail_qty) AS fail_qty
FROM fact_quality_inspection
GROUP BY work_order_number
),
-- =====================================================
-- 2. 工单进度计算与状态映射
-- =====================================================
work_order_progress AS (
SELECT
wb.work_order_id,
wb.work_order_number,
p.product_name,
p.product_category,
wb.status AS raw_status,
-- 状态映射
CASE wb.status
WHEN 'OPEN' THEN '待生产'
WHEN 'STARTED' THEN '生产中'
WHEN 'CLOSED' THEN '已完成'
ELSE '未知'
END AS status_name,
wb.planned_qty,
wb.completed_qty,
-- 完成进度
CASE WHEN wb.planned_qty > 0
THEN ROUND(wb.completed_qty * 100.0 / wb.planned_qty, 1)
ELSE 0 END AS completion_rate,
-- 剩余数量
GREATEST(wb.planned_qty - wb.completed_qty, 0) AS remaining_qty,
wb.start_time,
wb.last_update,
-- 已用时间(小时)
ROUND(EXTRACT(EPOCH FROM (CURRENT_TIMESTAMP - wb.start_time)) / 3600, 1) AS elapsed_hours,
-- 报工信息
COALESCE(ls.worker_count, 0) AS worker_count,
COALESCE(ls.total_report_qty, 0) AS total_report_qty,
COALESCE(ls.total_minutes, 0) AS total_work_minutes,
ls.last_report_time,
-- 质检信息
COALESCE(qs.pass_qty, 0) AS qc_pass_qty,
COALESCE(qs.fail_qty, 0) AS qc_fail_qty
FROM work_order_base wb
LEFT JOIN product_info p ON wb.product_id = p.product_id
LEFT JOIN labor_summary ls ON wb.work_order_number = ls.work_order_number
LEFT JOIN quality_summary qs ON wb.work_order_number = qs.work_order_number
),
-- =====================================================
-- 3. 异常节点检测
-- =====================================================
anomaly_detection AS (
SELECT
*,
-- 进度异常:进行中但完成率过低
CASE
WHEN raw_status = 'STARTED' AND elapsed_hours > 48 AND completion_rate < 20 THEN '进度严重滞后'
WHEN raw_status = 'STARTED' AND elapsed_hours > 24 AND completion_rate < 30 THEN '进度滞后'
ELSE NULL
END AS progress_anomaly,
-- 质量异常:废品率过高
CASE
WHEN qc_pass_qty + qc_fail_qty > 0
AND qc_fail_qty * 100.0 / (qc_pass_qty + qc_fail_qty) > 10 THEN '质量异常'
ELSE NULL
END AS quality_anomaly,
-- 报工异常:长时间无报工
CASE
WHEN raw_status = 'STARTED'
AND last_report_time IS NOT NULL
AND EXTRACT(EPOCH FROM (CURRENT_TIMESTAMP - last_report_time)) / 3600 > 24 THEN '报工停滞'
WHEN raw_status = 'STARTED'
AND last_report_time IS NULL
AND elapsed_hours > 24 THEN '无报工记录'
ELSE NULL
END AS labor_anomaly,
-- 效率异常:人效过低
CASE
WHEN total_work_minutes > 0
AND total_report_qty / (total_work_minutes / 60.0) < 5 THEN '效率偏低'
ELSE NULL
END AS efficiency_anomaly
FROM work_order_progress
)
-- =====================================================
-- 输出:工单执行进度明细
-- =====================================================
SELECT
work_order_number AS "工单号",
product_name AS "产品名称",
product_category AS "产品类别",
status_name AS "状态",
planned_qty AS "计划数量",
completed_qty AS "完成数量",
remaining_qty AS "剩余数量",
completion_rate AS "完成率(%)",
worker_count AS "参与人数",
ROUND(total_work_minutes / 60.0, 1) AS "累计工时(小时)",
elapsed_hours AS "已用时间(小时)",
-- 异常标记
COALESCE(progress_anomaly, '') ||
CASE WHEN progress_anomaly IS NOT NULL AND quality_anomaly IS NOT NULL THEN ',' ELSE '' END ||
COALESCE(quality_anomaly, '') ||
CASE WHEN (progress_anomaly IS NOT NULL OR quality_anomaly IS NOT NULL) AND labor_anomaly IS NOT NULL THEN ',' ELSE '' END ||
COALESCE(labor_anomaly, '') ||
CASE WHEN (progress_anomaly IS NOT NULL OR quality_anomaly IS NOT NULL OR labor_anomaly IS NOT NULL) AND efficiency_anomaly IS NOT NULL THEN ',' ELSE '' END ||
COALESCE(efficiency_anomaly, '') AS "异常标记",
-- 风险等级
CASE
WHEN progress_anomaly = '进度严重滞后' OR quality_anomaly IS NOT NULL THEN ''
WHEN progress_anomaly = '进度滞后' OR labor_anomaly IS NOT NULL THEN ''
WHEN efficiency_anomaly IS NOT NULL THEN ''
ELSE '-'
END AS "风险等级"
FROM anomaly_detection
ORDER BY
CASE raw_status WHEN 'STARTED' THEN 1 WHEN 'OPEN' THEN 2 ELSE 3 END,
CASE WHEN progress_anomaly IS NOT NULL THEN 0 ELSE 1 END,
completion_rate ASC;
-- =====================================================
-- 补充查询1工单状态分布汇总
-- =====================================================
WITH status_summary AS (
SELECT
CASE status
WHEN 'OPEN' THEN '待生产'
WHEN 'STARTED' THEN '生产中'
WHEN 'CLOSED' THEN '已完成'
ELSE '未知'
END AS status_name,
status AS raw_status,
COUNT(*) AS order_count,
SUM(planned_qty) AS total_planned,
SUM(completed_qty) AS total_completed
FROM fact_work_order
GROUP BY status
)
SELECT
status_name AS "状态",
order_count AS "工单数",
ROUND(order_count * 100.0 / SUM(order_count) OVER (), 1) AS "占比(%)",
ROUND(total_planned, 0) AS "计划总量",
ROUND(total_completed, 0) AS "完成总量",
CASE WHEN total_planned > 0
THEN ROUND(total_completed * 100.0 / total_planned, 1)
ELSE 0 END AS "完成率(%)"
FROM status_summary
ORDER BY
CASE raw_status WHEN 'STARTED' THEN 1 WHEN 'OPEN' THEN 2 ELSE 3 END;
-- =====================================================
-- 补充查询2异常工单预警清单
-- =====================================================
WITH work_order_anomaly AS (
SELECT
wo.work_order_number,
p.product_name,
wo.status,
wo.planned_qty,
wo.completed_qty,
CASE WHEN wo.planned_qty > 0
THEN ROUND(wo.completed_qty * 100.0 / wo.planned_qty, 1)
ELSE 0 END AS completion_rate,
ROUND(EXTRACT(EPOCH FROM (CURRENT_TIMESTAMP - wo.event_time_utc::timestamp)) / 3600, 1) AS elapsed_hours,
(SELECT MAX(lr.event_time_utc::timestamp)
FROM fact_labor_report lr
WHERE lr.work_order_number = wo.work_order_number) AS last_report_time
FROM fact_work_order wo
LEFT JOIN dim_product p ON wo.product_id = p.product_id AND p.is_current = 't'
WHERE wo.status = 'STARTED'
)
SELECT
work_order_number AS "工单号",
product_name AS "产品",
ROUND(planned_qty, 0) AS "计划数量",
ROUND(completed_qty, 0) AS "完成数量",
completion_rate AS "完成率(%)",
elapsed_hours AS "已用时间(小时)",
CASE
WHEN elapsed_hours > 48 AND completion_rate < 20 THEN '进度严重滞后'
WHEN elapsed_hours > 24 AND completion_rate < 30 THEN '进度滞后'
WHEN last_report_time IS NULL AND elapsed_hours > 24 THEN '无报工记录'
WHEN last_report_time IS NOT NULL
AND EXTRACT(EPOCH FROM (CURRENT_TIMESTAMP - last_report_time)) / 3600 > 24 THEN '报工停滞'
ELSE '正常'
END AS "异常类型",
CASE
WHEN elapsed_hours > 48 AND completion_rate < 20 THEN '立即跟进,排查生产瓶颈'
WHEN elapsed_hours > 24 AND completion_rate < 30 THEN '关注进度,协调资源'
WHEN last_report_time IS NULL AND elapsed_hours > 24 THEN '确认工单是否已开工'
WHEN last_report_time IS NOT NULL
AND EXTRACT(EPOCH FROM (CURRENT_TIMESTAMP - last_report_time)) / 3600 > 24 THEN '跟进报工情况'
ELSE '-'
END AS "处理建议"
FROM work_order_anomaly
WHERE elapsed_hours > 24 AND completion_rate < 50
OR (last_report_time IS NULL AND elapsed_hours > 24)
OR (last_report_time IS NOT NULL
AND EXTRACT(EPOCH FROM (CURRENT_TIMESTAMP - last_report_time)) / 3600 > 24)
ORDER BY
CASE
WHEN elapsed_hours > 48 AND completion_rate < 20 THEN 1
WHEN elapsed_hours > 24 AND completion_rate < 30 THEN 2
ELSE 3
END,
completion_rate ASC;
-- =====================================================
-- 补充查询3产品类别执行进度汇总
-- =====================================================
SELECT
p.product_category AS "产品类别",
COUNT(*) AS "工单数",
SUM(CASE WHEN wo.status = 'OPEN' THEN 1 ELSE 0 END) AS "待生产",
SUM(CASE WHEN wo.status = 'STARTED' THEN 1 ELSE 0 END) AS "生产中",
SUM(CASE WHEN wo.status = 'CLOSED' THEN 1 ELSE 0 END) AS "已完成",
ROUND(SUM(wo.planned_qty), 0) AS "计划总量",
ROUND(SUM(wo.completed_qty), 0) AS "完成总量",
CASE WHEN SUM(wo.planned_qty) > 0
THEN ROUND(SUM(wo.completed_qty) * 100.0 / SUM(wo.planned_qty), 1)
ELSE 0 END AS "整体完成率(%)"
FROM fact_work_order wo
LEFT JOIN dim_product p ON wo.product_id = p.product_id AND p.is_current = 't'
GROUP BY p.product_category
ORDER BY "工单数" DESC;
-- =====================================================
-- 补充查询4工单执行时间线
-- =====================================================
WITH timeline AS (
SELECT
wo.work_order_number,
p.product_name,
wo.status,
wo.event_time_utc::timestamp AS start_time,
wo.last_updated_utc::timestamp AS last_update,
CASE WHEN wo.status = 'CLOSED'
THEN ROUND(EXTRACT(EPOCH FROM (wo.last_updated_utc::timestamp - wo.event_time_utc::timestamp)) / 3600, 1)
ELSE ROUND(EXTRACT(EPOCH FROM (CURRENT_TIMESTAMP - wo.event_time_utc::timestamp)) / 3600, 1)
END AS duration_hours,
wo.planned_qty,
wo.completed_qty
FROM fact_work_order wo
LEFT JOIN dim_product p ON wo.product_id = p.product_id AND p.is_current = 't'
)
SELECT
work_order_number AS "工单号",
product_name AS "产品",
CASE status
WHEN 'OPEN' THEN '待生产'
WHEN 'STARTED' THEN '生产中'
WHEN 'CLOSED' THEN '已完成'
END AS "状态",
TO_CHAR(start_time, 'YYYY-MM-DD HH24:MI') AS "开始时间",
TO_CHAR(last_update, 'YYYY-MM-DD HH24:MI') AS "最后更新",
duration_hours AS "持续时间(小时)",
ROUND(planned_qty, 0) AS "计划数量",
ROUND(completed_qty, 0) AS "完成数量",
CASE WHEN planned_qty > 0
THEN ROUND(completed_qty * 100.0 / planned_qty, 1)
ELSE 0 END AS "完成率(%)"
FROM timeline
ORDER BY start_time DESC
LIMIT 50;
-- =====================================================
-- 补充查询5实时生产看板汇总
-- =====================================================
WITH current_stats AS (
SELECT
COUNT(*) AS total_orders,
SUM(CASE WHEN status = 'OPEN' THEN 1 ELSE 0 END) AS open_orders,
SUM(CASE WHEN status = 'STARTED' THEN 1 ELSE 0 END) AS started_orders,
SUM(CASE WHEN status = 'CLOSED' THEN 1 ELSE 0 END) AS closed_orders,
SUM(planned_qty) AS total_planned,
SUM(completed_qty) AS total_completed
FROM fact_work_order
),
anomaly_stats AS (
SELECT
COUNT(*) AS anomaly_count
FROM fact_work_order wo
WHERE wo.status = 'STARTED'
AND EXTRACT(EPOCH FROM (CURRENT_TIMESTAMP - wo.event_time_utc::timestamp)) / 3600 > 24
AND wo.completed_qty * 100.0 / NULLIF(wo.planned_qty, 0) < 30
),
today_stats AS (
SELECT
COUNT(*) AS today_completed
FROM fact_work_order
WHERE status = 'CLOSED'
AND last_updated_utc::date = CURRENT_DATE
)
SELECT
'总工单数' AS "指标",
cs.total_orders::text AS "数值",
'-' AS "状态"
FROM current_stats cs
UNION ALL
SELECT
'待生产',
cs.open_orders::text,
CASE WHEN cs.open_orders > 20 THEN '积压' ELSE '正常' END
FROM current_stats cs
UNION ALL
SELECT
'生产中',
cs.started_orders::text,
'进行中'
FROM current_stats cs
UNION ALL
SELECT
'已完成',
cs.closed_orders::text,
'正常'
FROM current_stats cs
UNION ALL
SELECT
'整体完成率',
ROUND(cs.total_completed * 100.0 / NULLIF(cs.total_planned, 0), 1)::text || '%',
CASE
WHEN cs.total_completed * 100.0 / NULLIF(cs.total_planned, 0) >= 80 THEN '良好'
WHEN cs.total_completed * 100.0 / NULLIF(cs.total_planned, 0) >= 50 THEN '正常'
ELSE '偏低'
END
FROM current_stats cs
UNION ALL
SELECT
'异常工单数',
ans.anomaly_count::text,
CASE WHEN ans.anomaly_count > 5 THEN '需关注' ELSE '正常' END
FROM anomaly_stats ans
UNION ALL
SELECT
'今日完成',
ts.today_completed::text,
'-'
FROM today_stats ts;