/* Reject 歷史績效表建置腳本 目的: - 以 DW_MES_LOTREJECTHISTORY 為主,建立可直接報表化的日彙總績效表 - 補齊產品/工站維度,並區分扣帳報廢與不扣帳報廢 */ /* ============================================================ 1) 建表 (執行一次) ============================================================ */ CREATE TABLE DWH.DW_PJ_REJECT_HISTORY_PERF_D ( TXN_DAY DATE NOT NULL, TXN_MONTH VARCHAR2(7) NOT NULL, WORKCENTER_GROUP VARCHAR2(40) NOT NULL, WORKCENTERSEQUENCE_GROUP NUMBER(10) NOT NULL, WORKCENTERNAME VARCHAR2(40) NOT NULL, SPECNAME VARCHAR2(40) NOT NULL, EQUIPMENTNAME VARCHAR2(255) NOT NULL, PRIMARY_EQUIPMENTNAME VARCHAR2(40) NOT NULL, PRODUCTLINENAME VARCHAR2(40) NOT NULL, PJ_TYPE VARCHAR2(40) NOT NULL, LOSSREASONNAME VARCHAR2(40) NOT NULL, REJECTCATEGORYNAME VARCHAR2(40) NOT NULL, REJECT_EVENT_ROWS NUMBER NOT NULL, AFFECTED_LOT_COUNT NUMBER NOT NULL, AFFECTED_WORKORDER_COUNT NUMBER NOT NULL, MOVEIN_QTY NUMBER NOT NULL, REJECT_QTY NUMBER NOT NULL, REJECT_TOTAL_QTY NUMBER NOT NULL, DEFECT_QTY NUMBER NOT NULL, STANDBY_QTY NUMBER NOT NULL, QTYTOPROCESS_QTY NUMBER NOT NULL, INPROCESS_QTY NUMBER NOT NULL, PROCESSED_QTY NUMBER NOT NULL, REJECT_RATE_PCT NUMBER(18, 4) NOT NULL, DEFECT_RATE_PCT NUMBER(18, 4) NOT NULL, REJECT_SHARE_PCT NUMBER(18, 4) NOT NULL, LAST_REFRESH_TS DATE NOT NULL ); CREATE INDEX DWH.IDX_RJH_PERF_D_01 ON DWH.DW_PJ_REJECT_HISTORY_PERF_D (TXN_DAY); CREATE INDEX DWH.IDX_RJH_PERF_D_02 ON DWH.DW_PJ_REJECT_HISTORY_PERF_D (WORKCENTER_GROUP, TXN_DAY); CREATE INDEX DWH.IDX_RJH_PERF_D_03 ON DWH.DW_PJ_REJECT_HISTORY_PERF_D (PRIMARY_EQUIPMENTNAME, TXN_DAY); CREATE INDEX DWH.IDX_RJH_PERF_D_04 ON DWH.DW_PJ_REJECT_HISTORY_PERF_D (LOSSREASONNAME, TXN_DAY); /* ============================================================ 2) 區間刷新 (可每日排程) 綁定參數: :start_date (YYYY-MM-DD) :end_date (YYYY-MM-DD) ============================================================ */ DELETE FROM DWH.DW_PJ_REJECT_HISTORY_PERF_D WHERE TXN_DAY >= TO_DATE(:start_date, 'YYYY-MM-DD') AND TXN_DAY < TO_DATE(:end_date, 'YYYY-MM-DD') + 1; INSERT /*+ APPEND */ INTO DWH.DW_PJ_REJECT_HISTORY_PERF_D ( TXN_DAY, TXN_MONTH, WORKCENTER_GROUP, WORKCENTERSEQUENCE_GROUP, WORKCENTERNAME, SPECNAME, EQUIPMENTNAME, PRIMARY_EQUIPMENTNAME, PRODUCTLINENAME, PJ_TYPE, LOSSREASONNAME, REJECTCATEGORYNAME, REJECT_EVENT_ROWS, AFFECTED_LOT_COUNT, AFFECTED_WORKORDER_COUNT, MOVEIN_QTY, REJECT_QTY, REJECT_TOTAL_QTY, DEFECT_QTY, STANDBY_QTY, QTYTOPROCESS_QTY, INPROCESS_QTY, PROCESSED_QTY, REJECT_RATE_PCT, DEFECT_RATE_PCT, REJECT_SHARE_PCT, LAST_REFRESH_TS ) WITH workcenter_map AS ( SELECT WORK_CENTER, MIN(WORK_CENTER_GROUP) KEEP ( DENSE_RANK FIRST ORDER BY WORKCENTERSEQUENCE_GROUP ) AS WORKCENTER_GROUP, MIN(WORKCENTERSEQUENCE_GROUP) AS WORKCENTERSEQUENCE_GROUP FROM DWH.DW_MES_SPEC_WORKCENTER_V WHERE WORK_CENTER IS NOT NULL GROUP BY WORK_CENTER ), reject_raw AS ( SELECT TRUNC(r.TXNDATE) AS TXN_DAY, TO_CHAR(TRUNC(r.TXNDATE), 'YYYY-MM') AS TXN_MONTH, r.CONTAINERID, NVL(TRIM(r.PJ_WORKORDER), TRIM(c.MFGORDERNAME)) AS PJ_WORKORDER, NVL(TRIM(c.PJ_TYPE), '(NA)') AS PJ_TYPE, NVL(TRIM(c.PRODUCTLINENAME), '(NA)') AS PRODUCTLINENAME, NVL(TRIM(r.WORKCENTERNAME), '(NA)') AS WORKCENTERNAME, NVL(TRIM(wm.WORKCENTER_GROUP), NVL(TRIM(r.WORKCENTERNAME), '(NA)')) AS WORKCENTER_GROUP, NVL(wm.WORKCENTERSEQUENCE_GROUP, 999) AS WORKCENTERSEQUENCE_GROUP, NVL(TRIM(r.SPECNAME), '(NA)') AS SPECNAME, NVL(TRIM(r.EQUIPMENTNAME), '(NA)') AS EQUIPMENTNAME, NVL( TRIM(REGEXP_SUBSTR(r.EQUIPMENTNAME, '[^,]+', 1, 1)), NVL(TRIM(r.EQUIPMENTNAME), '(NA)') ) AS PRIMARY_EQUIPMENTNAME, NVL(TRIM(r.LOSSREASONNAME), '(未填寫)') AS LOSSREASONNAME, NVL(TRIM(r.REJECTCATEGORYNAME), '(未填寫)') AS REJECTCATEGORYNAME, NVL(r.MOVEINQTY, 0) AS MOVEINQTY, NVL(r.REJECTQTY, 0) AS REJECT_QTY, NVL(r.STANDBYQTY, 0) AS STANDBY_QTY, NVL(r.QTYTOPROCESS, 0) AS QTYTOPROCESS_QTY, NVL(r.INPROCESSQTY, 0) AS INPROCESS_QTY, NVL(r.PROCESSEDQTY, 0) AS PROCESSED_QTY, NVL(r.REJECTQTY, 0) + NVL(r.STANDBYQTY, 0) + NVL(r.QTYTOPROCESS, 0) + NVL(r.INPROCESSQTY, 0) + NVL(r.PROCESSEDQTY, 0) AS REJECT_TOTAL_QTY, NVL(r.DEFECTQTY, 0) AS DEFECT_QTY, ROW_NUMBER() OVER ( PARTITION BY NVL( TRIM(r.HISTORYMAINLINEID), TRIM(r.CONTAINERID) || ':' || TO_CHAR(r.TXNDATE, 'YYYYMMDDHH24MISS') || ':' || NVL(TRIM(r.SPECID), '-') ) ORDER BY NVL(TRIM(r.LOSSREASONNAME), ' ') ) AS EVENT_RN FROM DWH.DW_MES_LOTREJECTHISTORY r LEFT JOIN DWH.DW_MES_CONTAINER c ON c.CONTAINERID = r.CONTAINERID LEFT JOIN workcenter_map wm ON wm.WORK_CENTER = r.WORKCENTERNAME WHERE r.TXNDATE >= TO_DATE(:start_date, 'YYYY-MM-DD') AND r.TXNDATE < TO_DATE(:end_date, 'YYYY-MM-DD') + 1 ), daily_agg AS ( SELECT TXN_DAY, TXN_MONTH, WORKCENTER_GROUP, WORKCENTERSEQUENCE_GROUP, WORKCENTERNAME, SPECNAME, EQUIPMENTNAME, PRIMARY_EQUIPMENTNAME, PRODUCTLINENAME, PJ_TYPE, LOSSREASONNAME, REJECTCATEGORYNAME, COUNT(*) AS REJECT_EVENT_ROWS, COUNT(DISTINCT CONTAINERID) AS AFFECTED_LOT_COUNT, COUNT(DISTINCT PJ_WORKORDER) AS AFFECTED_WORKORDER_COUNT, SUM(CASE WHEN EVENT_RN = 1 THEN MOVEINQTY ELSE 0 END) AS MOVEIN_QTY, SUM(REJECT_QTY) AS REJECT_QTY, SUM(REJECT_TOTAL_QTY) AS REJECT_TOTAL_QTY, SUM(DEFECT_QTY) AS DEFECT_QTY, SUM(STANDBY_QTY) AS STANDBY_QTY, SUM(QTYTOPROCESS_QTY) AS QTYTOPROCESS_QTY, SUM(INPROCESS_QTY) AS INPROCESS_QTY, SUM(PROCESSED_QTY) AS PROCESSED_QTY FROM reject_raw GROUP BY TXN_DAY, TXN_MONTH, WORKCENTER_GROUP, WORKCENTERSEQUENCE_GROUP, WORKCENTERNAME, SPECNAME, EQUIPMENTNAME, PRIMARY_EQUIPMENTNAME, PRODUCTLINENAME, PJ_TYPE, LOSSREASONNAME, REJECTCATEGORYNAME ) SELECT TXN_DAY, TXN_MONTH, WORKCENTER_GROUP, WORKCENTERSEQUENCE_GROUP, WORKCENTERNAME, SPECNAME, EQUIPMENTNAME, PRIMARY_EQUIPMENTNAME, PRODUCTLINENAME, PJ_TYPE, LOSSREASONNAME, REJECTCATEGORYNAME, REJECT_EVENT_ROWS, AFFECTED_LOT_COUNT, AFFECTED_WORKORDER_COUNT, MOVEIN_QTY, REJECT_QTY, REJECT_TOTAL_QTY, DEFECT_QTY, STANDBY_QTY, QTYTOPROCESS_QTY, INPROCESS_QTY, PROCESSED_QTY, CASE WHEN MOVEIN_QTY = 0 THEN 0 ELSE ROUND(REJECT_TOTAL_QTY * 100 / MOVEIN_QTY, 4) END AS REJECT_RATE_PCT, CASE WHEN MOVEIN_QTY = 0 THEN 0 ELSE ROUND(DEFECT_QTY * 100 / MOVEIN_QTY, 4) END AS DEFECT_RATE_PCT, CASE WHEN (REJECT_TOTAL_QTY + DEFECT_QTY) = 0 THEN 0 ELSE ROUND(REJECT_TOTAL_QTY * 100 / (REJECT_TOTAL_QTY + DEFECT_QTY), 4) END AS REJECT_SHARE_PCT, SYSDATE AS LAST_REFRESH_TS FROM daily_agg; COMMIT; /* ============================================================ 3) 快速驗證查詢 ============================================================ */ SELECT TXN_DAY, WORKCENTER_GROUP, SUM(MOVEIN_QTY) AS MOVEIN_QTY, SUM(REJECT_QTY) AS REJECT_QTY, SUM(REJECT_TOTAL_QTY) AS REJECT_TOTAL_QTY, SUM(DEFECT_QTY) AS DEFECT_QTY, ROUND(SUM(REJECT_TOTAL_QTY) * 100 / NULLIF(SUM(MOVEIN_QTY), 0), 4) AS REJECT_RATE_PCT FROM DWH.DW_PJ_REJECT_HISTORY_PERF_D WHERE TXN_DAY BETWEEN TO_DATE(:start_date, 'YYYY-MM-DD') AND TO_DATE(:end_date, 'YYYY-MM-DD') GROUP BY TXN_DAY, WORKCENTER_GROUP ORDER BY TXN_DAY DESC, WORKCENTER_GROUP;