-- ===================================================== -- 工单执行进度与异常节点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;