-- =====================================================
-- 人效-产值-损耗三维模型仪表盘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;
