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

194 lines
7.7 KiB
SQL

-- =====================================================
-- 人效-产值-损耗三维模型仪表盘SQL
-- Efficiency-Output-Loss 3D Model Dashboard
-- 数据库: PostgreSQL
-- 维度: 产品类别(化工/机械/电子)作为部门维度
-- =====================================================
-- 1. 部门级综合仪表盘(主查询)
WITH
labor_stats AS (
SELECT
p.product_category AS department,
COUNT(DISTINCT lr.worker_name) AS worker_count,
SUM(lr.duration_minutes) AS total_work_minutes,
SUM(lr.report_qty) AS total_output_qty,
COUNT(DISTINCT lr.work_order_number) AS work_order_count
FROM fact_labor_report lr
INNER JOIN dim_product p ON lr.product_id = p.product_id AND p.is_current = 't'
GROUP BY p.product_category
),
work_order_stats AS (
SELECT
p.product_category AS department,
COUNT(*) AS total_work_orders,
SUM(wo.planned_qty) AS total_planned_qty,
SUM(wo.completed_qty) AS total_completed_qty,
SUM(CASE WHEN wo.status = 'CLOSED' THEN 1 ELSE 0 END) AS closed_orders,
SUM(CASE WHEN wo.status = 'STARTED' THEN 1 ELSE 0 END) AS started_orders,
SUM(CASE WHEN wo.status = 'OPEN' THEN 1 ELSE 0 END) AS open_orders
FROM fact_work_order wo
INNER JOIN dim_product p ON wo.product_id = p.product_id AND p.is_current = 't'
GROUP BY p.product_category
),
quality_stats AS (
SELECT
p.product_category AS department,
SUM(qi.pass_qty) AS total_pass_qty,
SUM(qi.fail_qty) AS total_fail_qty,
COUNT(*) AS inspection_count
FROM fact_quality_inspection qi
INNER JOIN dim_product p ON qi.product_id = p.product_id AND p.is_current = 't'
GROUP BY p.product_category
),
sales_stats AS (
SELECT
AVG(deal_amount) AS avg_order_amount,
SUM(deal_amount) AS total_sales_amount,
COUNT(*) AS order_count
FROM fact_sales_order
),
scrap_stats AS (
SELECT COUNT(*) AS total_scrap_count
FROM fact_scrap
)
SELECT
ls.department,
-- 人效维度
ls.worker_count,
ROUND(ls.total_work_minutes / 60.0, 2) AS total_work_hours,
ls.total_output_qty,
ROUND(ls.total_output_qty / NULLIF(ls.worker_count, 0), 2) AS output_per_worker,
ROUND(ls.total_output_qty / NULLIF(ls.total_work_minutes / 60.0, 0), 2) AS output_per_hour,
ROUND(
ls.total_output_qty / NULLIF(ls.worker_count, 0) / NULLIF(ls.total_work_minutes / 60.0 / ls.worker_count, 0),
2
) AS efficiency_index,
-- 产值维度
ws.total_planned_qty AS planned_qty,
ws.total_completed_qty AS completed_qty,
ROUND(ws.total_completed_qty / NULLIF(ws.total_planned_qty, 0) * 100, 2) AS plan_completion_rate,
ROUND(ws.total_completed_qty * ss.avg_order_amount / 100, 2) AS estimated_output_value,
ROUND(ws.total_completed_qty * ss.avg_order_amount / 100 / NULLIF(ls.worker_count, 0), 2) AS output_value_per_worker,
-- 损耗维度
qs.total_pass_qty AS qc_pass_qty,
qs.total_fail_qty AS qc_fail_qty,
ROUND(qs.total_fail_qty / NULLIF(qs.total_pass_qty + qs.total_fail_qty, 0) * 100, 2) AS defect_rate,
ROUND((ws.total_planned_qty - ws.total_completed_qty) / NULLIF(ws.total_planned_qty, 0) * 100, 2) AS production_loss_rate,
-- 综合评分
ROUND(
(ls.total_output_qty / NULLIF(ls.worker_count, 0) / NULLIF(ls.total_work_minutes / 60.0 / ls.worker_count, 0)) * 0.4 +
(ws.total_completed_qty / NULLIF(ws.total_planned_qty, 0) * 100) * 0.35 +
(qs.total_pass_qty / NULLIF(qs.total_pass_qty + qs.total_fail_qty, 0) * 100) * 0.25,
2
) AS performance_score,
-- 预警等级
CASE
WHEN (qs.total_fail_qty / NULLIF(qs.total_pass_qty + qs.total_fail_qty, 0) * 100) >= 10
OR (ws.total_completed_qty / NULLIF(ws.total_planned_qty, 0) * 100) < 50
THEN 'RED'
WHEN (qs.total_fail_qty / NULLIF(qs.total_pass_qty + qs.total_fail_qty, 0) * 100) >= 5
OR (ws.total_completed_qty / NULLIF(ws.total_planned_qty, 0) * 100) < 70
THEN 'YELLOW'
ELSE 'GREEN'
END AS warning_level
FROM labor_stats ls
LEFT JOIN work_order_stats ws ON ls.department = ws.department
LEFT JOIN quality_stats qs ON ls.department = qs.department
CROSS JOIN sales_stats ss
CROSS JOIN scrap_stats scr
ORDER BY performance_score DESC;
-- =====================================================
-- 2. 人员级明细报表
-- =====================================================
SELECT
lr.worker_name,
p.product_category AS department,
COUNT(DISTINCT lr.work_order_number) AS work_order_count,
SUM(lr.duration_minutes) AS total_work_minutes,
ROUND(SUM(lr.duration_minutes) / 60.0, 2) AS total_work_hours,
SUM(lr.report_qty) AS total_output,
ROUND(SUM(lr.report_qty) / NULLIF(SUM(lr.duration_minutes) / 60.0, 0), 2) AS output_per_hour,
RANK() OVER (PARTITION BY p.product_category ORDER BY SUM(lr.report_qty) DESC) AS dept_output_rank
FROM fact_labor_report lr
INNER JOIN dim_product p ON lr.product_id = p.product_id AND p.is_current = 't'
GROUP BY lr.worker_name, p.product_category
ORDER BY p.product_category, total_output DESC;
-- =====================================================
-- 3. 月度趋势分析
-- =====================================================
SELECT
TO_CHAR(DATE_TRUNC('month', lr.event_time_utc::timestamp), 'YYYY-MM') AS month,
p.product_category AS department,
COUNT(DISTINCT lr.worker_name) AS active_worker_count,
SUM(lr.duration_minutes) AS total_work_minutes,
SUM(lr.report_qty) AS total_output,
ROUND(SUM(lr.report_qty) / NULLIF(COUNT(DISTINCT lr.worker_name), 0), 2) AS output_per_worker,
ROUND(SUM(lr.report_qty) / NULLIF(SUM(lr.duration_minutes) / 60.0, 0), 2) AS output_per_hour
FROM fact_labor_report lr
INNER JOIN dim_product p ON lr.product_id = p.product_id AND p.is_current = 't'
GROUP BY DATE_TRUNC('month', lr.event_time_utc::timestamp), p.product_category
ORDER BY month DESC, p.product_category;
-- =====================================================
-- 4. 产品级损耗分析
-- =====================================================
SELECT
p.product_category AS department,
p.product_name,
p.product_code,
COALESCE(SUM(qi.pass_qty), 0) AS pass_qty,
COALESCE(SUM(qi.fail_qty), 0) AS fail_qty,
ROUND(
COALESCE(SUM(qi.fail_qty), 0) /
NULLIF(COALESCE(SUM(qi.pass_qty), 0) + COALESCE(SUM(qi.fail_qty), 0), 0) * 100,
2
) AS defect_rate,
CASE
WHEN COALESCE(SUM(qi.fail_qty), 0) /
NULLIF(COALESCE(SUM(qi.pass_qty), 0) + COALESCE(SUM(qi.fail_qty), 0), 0) * 100 >= 10
THEN 'HIGH'
WHEN COALESCE(SUM(qi.fail_qty), 0) /
NULLIF(COALESCE(SUM(qi.pass_qty), 0) + COALESCE(SUM(qi.fail_qty), 0), 0) * 100 >= 5
THEN 'MEDIUM'
ELSE 'LOW'
END AS loss_level
FROM dim_product p
LEFT JOIN fact_quality_inspection qi ON p.product_id = qi.product_id
WHERE p.is_current = 't'
GROUP BY p.product_category, p.product_name, p.product_code
ORDER BY defect_rate DESC NULLS LAST;
-- =====================================================
-- 5. 工单完成率分析
-- =====================================================
SELECT
p.product_category AS department,
wo.status,
COUNT(*) AS order_count,
SUM(wo.planned_qty) AS total_planned,
SUM(wo.completed_qty) AS total_completed,
ROUND(SUM(wo.completed_qty) / NULLIF(SUM(wo.planned_qty), 0) * 100, 2) AS completion_rate,
ROUND(AVG(wo.completed_qty / NULLIF(wo.planned_qty, 0) * 100), 2) AS avg_completion_rate
FROM fact_work_order wo
INNER JOIN dim_product p ON wo.product_id = p.product_id AND p.is_current = 't'
GROUP BY p.product_category, wo.status
ORDER BY p.product_category, wo.status;