制造业质量控制数仓实践(SPC 统计过程控制)

将 MES 系统的实时检测数据和人工抽样记录构建为三层质量控制数仓,支持 SPC 控制图、Cpk 工序能力分析和缺陷 Pareto 分析。本文以 1,000 条制造缺陷记录(覆盖 100 种产品、3 条生产线、3 类缺陷类型)为数据集,端到端演示 Kafka PIPE → Bronze → Silver → Gold 的完整构建过程,并覆盖 Bloomfilter Index、SQL UDF、Dynamic Table、滑动窗口统计四项平台能力的落地用法。


概述

制造业质量控制的典型数据链路是:在线检测上报 → 实时接入 → 原始存储(Bronze)→ 清洗打标(Silver)→ SPC 指标聚合(Gold)

云器 Lakehouse 通过以下组合解决几个核心问题:

问题云器解决方案
MES 检测数据实时高频写入Kafka PIPE 持续摄取,无需手写消费者
人工抽样 CSV 批量导入Volume + COPY INTO,支持增量加载
Bronze → Silver → Gold 自动增量计算Dynamic Table,声明式 SQL,系统自动调度依赖链
product_id
product_id
高基数列,点查频繁
Bloomfilter Index,按需快速过滤
Cpk 工序能力和严重程度评分逻辑可复用SQL UDF,封装公式,Silver/Gold 层均可调用
UCL/LCL 滑动窗口控制限计算窗口函数 + CTE,分产品计算过程均值和 3σ 控制限
大规模历史检测数据按生产线高效查询Gold 层 Dynamic Table 静态分区(
PARTITIONED BY production_line
PARTITIONED BY production_line

涉及的 SQL 命令

命令 / 函数用途说明
CREATE TABLE
CREATE TABLE
建 Bronze 层原始缺陷事件表和产品主数据表普通表,作为 Dynamic Table 上游
CREATE BLOOMFILTER INDEX
CREATE BLOOMFILTER INDEX
product_id
product_id
列创建 Bloomfilter 索引
适合高基数列的等值过滤
CREATE PIPE
CREATE PIPE
创建 Kafka 持续摄取管道绑定到 Bronze 层目标表
COPY INTO
COPY INTO
批量导入人工抽样 CSV 文件从 Volume 加载,支持增量
CREATE FUNCTION
CREATE FUNCTION
创建 SQL UDF
calc_cpk
calc_cpk
severity_score
severity_score
封装 Cpk 计算和严重程度评分
CREATE DYNAMIC TABLE
CREATE DYNAMIC TABLE
创建 Silver / Gold 层增量计算表系统自动识别上游变更并增量刷新
REFRESH DYNAMIC TABLE
REFRESH DYNAMIC TABLE
手动触发一次刷新初次构建或调试时使用
AVG / STDDEV_SAMP ... OVER
AVG / STDDEV_SAMP ... OVER
滑动窗口均值和标准差计算 UCL/LCL 过程控制限

前置准备

本文所有示例在

best_practice_manufacturing_spc
best_practice_manufacturing_spc
Schema 下运行。

CREATE SCHEMA IF NOT EXISTS best_practice_manufacturing_spc;


Bronze 层:原始缺陷事件表

建表

CREATE TABLE IF NOT EXISTS best_practice_manufacturing_spc.doc_defect_events ( defect_id INT, product_id INT, defect_type STRING, defect_date DATE, defect_location STRING, severity STRING, inspection_method STRING, repair_cost DOUBLE, ingest_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP() );

ingest_time
ingest_time
使用
DEFAULT CURRENT_TIMESTAMP()
DEFAULT CURRENT_TIMESTAMP()
,Kafka PIPE 写入时自动填充,无需在消息体中携带。

创建 Bloomfilter Index

后续 Silver 和 Gold 层都会按

product_id
product_id
过滤,该列为高基数列(100 种产品),适合 Bloomfilter Index。

CREATE BLOOMFILTER INDEX idx_bf_product_id ON TABLE doc_defect_events (product_id);

产品主数据表

CREATE TABLE IF NOT EXISTS best_practice_manufacturing_spc.doc_product_master ( product_id INT, product_name STRING, production_line STRING, product_category STRING, spec_ucl DOUBLE, -- 规格上限 (USL) spec_lcl DOUBLE, -- 规格下限 (LSL) spec_target DOUBLE -- 目标值 );

spec_ucl
spec_ucl
/
spec_lcl
spec_lcl
是产品设计规格,用于 Cpk 计算;生产过程控制图的 UCL/LCL 基于实际数据计算(见 Silver 层)。

配置 Kafka PIPE(实时接入)

方式一:通过 Kafka 实际写入(推荐)

正式环境中,MES 系统将检测结果推送到 Kafka Topic,PIPE 自动消费并写入 Bronze 层。Python 生产者示例:

from kafka import KafkaProducer import json, datetime, random producer = KafkaProducer( bootstrap_servers=['<kafka-broker>:9092'], value_serializer=lambda v: json.dumps(v).encode('utf-8') ) def send_defect_event(defect_id, product_id): message = { "defect_id": defect_id, "product_id": product_id, "defect_type": random.choice(["Structural", "Functional", "Cosmetic"]), "defect_date": datetime.date.today().isoformat(), "defect_location": random.choice(["Component", "Internal", "Surface"]), "severity": random.choice(["Minor", "Moderate", "Critical"]), "inspection_method": random.choice(["Automated Testing", "Visual Inspection", "Manual Testing"]), "repair_cost": round(random.uniform(10.0, 1000.0), 2) } producer.send('mes_defect_events', value=message) producer.flush() # 模拟发送 10 条 for i in range(1001, 1011): send_defect_event(i, random.randint(1, 100)) producer.close()

创建 Kafka PIPE(DDL 阶段会尝试连接 broker 验证):

CREATE TABLE IF NOT EXISTS best_practice_manufacturing_spc.kafka_raw_defects (value STRING); CREATE PIPE IF NOT EXISTS best_practice_manufacturing_spc.pipe_defect_events VIRTUAL_CLUSTER = 'DEFAULT' BATCH_INTERVAL_IN_SECONDS = '60' AS COPY INTO best_practice_manufacturing_spc.kafka_raw_defects FROM ( SELECT CAST(value AS STRING) AS value FROM READ_KAFKA( '<kafka-broker>:9092', 'mes_defect_events', '', 'cz_mes_consumer', '','','','', 'raw', 'raw', 0, map() ) );

方式二:INSERT 模拟(无 Kafka 环境时)

如果暂未配置 Kafka,可先将数据保存为本地 CSV 文件,通过 cz-cli 上传到 User Volume 后用 COPY INTO 导入(推荐):

从本地 CSV 导入(推荐)

-- 第一步:通过 SQL PUT 将本地 CSV 文件上传到 User Volume PUT '/path/to/defect_events_data.csv' TO USER VOLUME FILE 'defect_events_data.csv';

-- 第二步:从 User Volume COPY INTO 表 COPY INTO best_practice_manufacturing_spc.doc_defect_events FROM USER VOLUME USING csv OPTIONS('header'='true', 'sep'=',', 'nullValue'='') FILES ('defect_events_data.csv');

也可直接内联插入小批量测试数据(不需要 CSV 文件):

本文使用 Kaggle 数据集(

fahmidachowdhury/manufacturing-defects
fahmidachowdhury/manufacturing-defects
,1,000 条)通过批量 INSERT 写入 Bronze 层,验证完整计算链路:

INSERT INTO best_practice_manufacturing_spc.doc_defect_events (defect_id, product_id, defect_type, defect_date, defect_location, severity, inspection_method, repair_cost) VALUES (1, 15, 'Structural', CAST('2024-06-06' AS DATE), 'Component', 'Minor', 'Visual Inspection', 245.47), (2, 6, 'Functional', CAST('2024-04-26' AS DATE), 'Component', 'Minor', 'Visual Inspection', 26.87), (3, 84, 'Structural', CAST('2024-02-15' AS DATE), 'Internal', 'Minor', 'Automated Testing', 835.81), (4, 10, 'Functional', CAST('2024-03-28' AS DATE), 'Internal', 'Critical', 'Automated Testing', 444.47) -- ... 共 1,000 条 ;

验证 Bronze 层行数:

SELECT COUNT(*) AS total_rows FROM best_practice_manufacturing_spc.doc_defect_events;

total_rows ---------- 1000

查看数据分布概况:

SELECT defect_type, COUNT(*) AS defect_count FROM best_practice_manufacturing_spc.doc_defect_events GROUP BY defect_type ORDER BY defect_count DESC;

defect_type | defect_count ------------+------------- Structural | 352 Functional | 339 Cosmetic | 309

人工抽样 CSV 导入(Volume + COPY INTO)

将人工抽样表格上传到 Volume 后,通过 COPY INTO 批量导入,支持自动跳过已导入文件(幂等):

COPY INTO best_practice_manufacturing_spc.doc_defect_events (defect_id, product_id, defect_type, defect_date, defect_location, severity, inspection_method, repair_cost) FROM ( SELECT $1::INT AS defect_id, $2::INT AS product_id, $3 AS defect_type, $4::DATE AS defect_date, $5 AS defect_location, $6 AS severity, $7 AS inspection_method, $8::DOUBLE AS repair_cost FROM @best_practice_manufacturing_spc.sampling_volume/defects_data.csv ) USING csv OPTIONS('header'='true', 'sep'=',');


SQL UDF:Cpk 与严重程度评分

Cpk 工序能力指数

Cpk(过程能力指数)衡量生产过程相对于规格要求的居中程度和波动水平。Cpk ≥ 1.33 表示过程能力良好,< 1.0 表示过程不满足规格要求。

公式:

Cpk = min((USL - μ) / (3σ), (μ - LSL) / (3σ))
Cpk = min((USL - μ) / (3σ), (μ - LSL) / (3σ))

CREATE OR REPLACE FUNCTION best_practice_manufacturing_spc.calc_cpk( avg_val DOUBLE, std_val DOUBLE, ucl DOUBLE, lcl DOUBLE ) RETURNS DOUBLE AS CASE WHEN std_val <= 0 THEN NULL ELSE LEAST((ucl - avg_val) / (3.0 * std_val), (avg_val - lcl) / (3.0 * std_val)) END;

验证函数(目标值居中,过程标准差 1.2,规格范围 ±5):

SELECT best_practice_manufacturing_spc.calc_cpk(100.5, 1.2, 105.0, 95.0) AS cpk_sample;

cpk_sample ---------- 1.25

严重程度评分 UDF

将文字型 severity 映射为数值评分,便于 Silver 层聚合计算加权风险:

CREATE OR REPLACE FUNCTION best_practice_manufacturing_spc.severity_score( severity STRING ) RETURNS INT AS CASE severity WHEN 'Critical' THEN 3 WHEN 'Moderate' THEN 2 WHEN 'Minor' THEN 1 ELSE 0 END;


Silver 层 Dynamic Table:清洗与维度关联

Silver 层在 Bronze 原始缺陷事件基础上完成两件事:

  1. LEFT JOIN
    doc_product_master
    doc_product_master
    ,为每条事件关联生产线、产品分类、规格上下限等维度字段
  2. 计算
    severity_score
    severity_score
    is_critical
    is_critical
    标记,方便 Gold 层直接聚合

CREATE DYNAMIC TABLE IF NOT EXISTS best_practice_manufacturing_spc.silver_defect_enriched REFRESH INTERVAL 10 MINUTE VCLUSTER DEFAULT AS SELECT e.defect_id, e.product_id, e.defect_type, e.defect_date, e.defect_location, e.severity, e.inspection_method, e.repair_cost, e.ingest_time, p.product_name, p.production_line, p.product_category, p.spec_ucl, p.spec_lcl, p.spec_target, best_practice_manufacturing_spc.severity_score(e.severity) AS severity_score, CASE WHEN e.severity = 'Critical' THEN 1 ELSE 0 END AS is_critical, DATE_TRUNC('month', e.defect_date) AS defect_month FROM best_practice_manufacturing_spc.doc_defect_events e LEFT JOIN best_practice_manufacturing_spc.doc_product_master p ON e.product_id = p.product_id;

手动触发首次刷新:

REFRESH DYNAMIC TABLE best_practice_manufacturing_spc.silver_defect_enriched; SELECT COUNT(*) AS silver_count FROM best_practice_manufacturing_spc.silver_defect_enriched;

silver_count ------------ 1000

查看按生产线和缺陷类型的分布(Silver 层直查):

SELECT production_line, defect_type, COUNT(*) AS defect_count, SUM(is_critical) AS critical_count, ROUND(AVG(repair_cost), 2) AS avg_repair_cost FROM best_practice_manufacturing_spc.silver_defect_enriched GROUP BY production_line, defect_type ORDER BY production_line, defect_count DESC;

production_line | defect_type | defect_count | critical_count | avg_repair_cost ----------------+-------------+--------------+----------------+---------------- Line-1 | Structural | 114 | 40 | 494.87 Line-1 | Functional | 111 | 38 | 517.15 Line-1 | Cosmetic | 94 | 35 | 497.84 Line-2 | Structural | 116 | 30 | 470.31 Line-2 | Cosmetic | 113 | 35 | 499.46 Line-2 | Functional | 104 | 35 | 521.81 Line-3 | Functional | 124 | 41 | 485.75 Line-3 | Structural | 122 | 42 | 540.60 Line-3 | Cosmetic | 102 | 37 | 544.72

结果解读:Line-3 的 Structural 缺陷均价最高(540.60 元),且 Critical 占比(42/122 = 34.4%)也高于 Line-1 和 Line-2 的同类缺陷,是返修成本的重点治理对象。


SPC 控制图:滑动窗口 UCL/LCL 计算

SPC 控制图通过统计过程均值(μ)和标准差(σ)计算过程控制上下限(UCL/LCL),识别过程失控点。本节用窗口函数实现 c 控制图(计数型),适合缺陷计数数据。

控制限公式

  • UCL = μ + 3σ
    UCL = μ + 3σ
  • LCL = max(0, μ − 3σ)
    LCL = max(0, μ − 3σ)
    (计数数据下限不能为负)

WITH monthly_stats AS ( -- 先按产品+月份聚合,避免二层窗口聚合嵌套错误 SELECT product_id, defect_month, COUNT(*) AS monthly_defects FROM best_practice_manufacturing_spc.silver_defect_enriched GROUP BY product_id, defect_month ) SELECT product_id, defect_month, monthly_defects, -- 滑动 3 个月均值(移动平均) ROUND(AVG(monthly_defects) OVER ( PARTITION BY product_id ORDER BY defect_month ROWS BETWEEN 2 PRECEDING AND CURRENT ROW ), 2) AS rolling_3m_avg, -- 全历史过程均值(控制图中心线) ROUND(AVG(monthly_defects) OVER (PARTITION BY product_id), 2) AS process_mean, ROUND(STDDEV_SAMP(monthly_defects) OVER (PARTITION BY product_id), 2) AS process_std, -- UCL / LCL ROUND(AVG(monthly_defects) OVER (PARTITION BY product_id) + 3 * STDDEV_SAMP(monthly_defects) OVER (PARTITION BY product_id), 2) AS ucl, ROUND(GREATEST(0, AVG(monthly_defects) OVER (PARTITION BY product_id) - 3 * STDDEV_SAMP(monthly_defects) OVER (PARTITION BY product_id)), 2) AS lcl, -- 过程状态判断 CASE WHEN monthly_defects > AVG(monthly_defects) OVER (PARTITION BY product_id) + 3 * STDDEV_SAMP(monthly_defects) OVER (PARTITION BY product_id) THEN 'OUT_OF_CONTROL' WHEN monthly_defects < GREATEST(0, AVG(monthly_defects) OVER (PARTITION BY product_id) - 3 * STDDEV_SAMP(monthly_defects) OVER (PARTITION BY product_id)) THEN 'OUT_OF_CONTROL' ELSE 'IN_CONTROL' END AS spc_status FROM monthly_stats WHERE product_id IN (10, 14, 15) ORDER BY product_id, defect_month;

product_id | defect_month | monthly_defects | rolling_3m_avg | process_mean | process_std | ucl | lcl | spc_status -----------+---------------------+-----------------+----------------+--------------+-------------+------+-----+----------- 10 | 2024-01-01T00:00:00 | 2 | 2.0 | 2.67 | 1.21 | 6.30 | 0 | IN_CONTROL 10 | 2024-02-01T00:00:00 | 2 | 2.0 | 2.67 | 1.21 | 6.30 | 0 | IN_CONTROL 10 | 2024-03-01T00:00:00 | 3 | 2.33 | 2.67 | 1.21 | 6.30 | 0 | IN_CONTROL 10 | 2024-04-01T00:00:00 | 1 | 2.0 | 2.67 | 1.21 | 6.30 | 0 | IN_CONTROL 10 | 2024-05-01T00:00:00 | 4 | 2.67 | 2.67 | 1.21 | 6.30 | 0 | IN_CONTROL 10 | 2024-06-01T00:00:00 | 4 | 3.0 | 2.67 | 1.21 | 6.30 | 0 | IN_CONTROL 14 | 2024-01-01T00:00:00 | 1 | 1.0 | 2.20 | 1.10 | 5.49 | 0 | IN_CONTROL 14 | 2024-02-01T00:00:00 | 2 | 1.50 | 2.20 | 1.10 | 5.49 | 0 | IN_CONTROL 14 | 2024-04-01T00:00:00 | 2 | 1.67 | 2.20 | 1.10 | 5.49 | 0 | IN_CONTROL 14 | 2024-05-01T00:00:00 | 2 | 2.0 | 2.20 | 1.10 | 5.49 | 0 | IN_CONTROL 14 | 2024-06-01T00:00:00 | 4 | 2.67 | 2.20 | 1.10 | 5.49 | 0 | IN_CONTROL 15 | 2024-02-01T00:00:00 | 2 | 2.0 | 2.0 | 0.71 | 4.12 | 0 | IN_CONTROL 15 | 2024-03-01T00:00:00 | 2 | 2.0 | 2.0 | 0.71 | 4.12 | 0 | IN_CONTROL 15 | 2024-04-01T00:00:00 | 1 | 1.67 | 2.0 | 0.71 | 4.12 | 0 | IN_CONTROL 15 | 2024-05-01T00:00:00 | 3 | 2.0 | 2.0 | 0.71 | 4.12 | 0 | IN_CONTROL 15 | 2024-06-01T00:00:00 | 2 | 2.0 | 2.0 | 0.71 | 4.12 | 0 | IN_CONTROL

结果解读:示例产品(10、14、15)在观测周期内均处于 IN_CONTROL 状态,各月缺陷数未超出 UCL。产品 15 的过程波动最小(σ = 0.71),说明其检测过程最稳定;产品 14 的 6 月缺陷数为 4,已接近 UCL(5.49),建议关注后续趋势。


Cpk 分析:按生产线计算工序能力

calc_cpk
calc_cpk
UDF 应用于按生产线汇总的修复费用数据(以修复费用替代物理尺寸测量值做演示):

WITH line_stats AS ( SELECT production_line, COUNT(*) AS total_defects, ROUND(AVG(repair_cost), 2) AS avg_repair_cost, ROUND(STDDEV_SAMP(repair_cost), 2) AS std_repair_cost FROM best_practice_manufacturing_spc.silver_defect_enriched GROUP BY production_line ) SELECT production_line, total_defects, avg_repair_cost, std_repair_cost, ROUND(best_practice_manufacturing_spc.calc_cpk( avg_repair_cost, std_repair_cost, 1000.0, -- 规格上限(最大可接受修复费用) 0.0 -- 规格下限 ), 3) AS repair_cost_cpk FROM line_stats ORDER BY production_line;

production_line | total_defects | avg_repair_cost | std_repair_cost | repair_cost_cpk ----------------+---------------+-----------------+-----------------+---------------- Line-1 | 319 | 503.50 | 302.99 | 0.546 Line-2 | 333 | 496.29 | 281.61 | 0.587 Line-3 | 348 | 522.27 | 284.83 | 0.559

结果解读:三条生产线的 repair_cost_cpk 均远低于 1.0,表明修复费用分布相对于规格范围(0–1000 元)波动过大,主要原因是费用分布范围宽(10–1000 元),标准差约为 290 元。Line-2 的 Cpk 最高(0.587),费用集中程度略优于其他两条线。


Gold 层 Dynamic Table:生产线月度聚合

Gold 层以

production_line
production_line
+
defect_month
defect_month
为粒度聚合 Silver 层数据,输出月度缺陷趋势和 Critical 比率,用于质量管理看板。

CREATE DYNAMIC TABLE IF NOT EXISTS best_practice_manufacturing_spc.gold_production_line_monthly PARTITIONED BY (production_line) REFRESH INTERVAL 10 MINUTE VCLUSTER DEFAULT TBLPROPERTIES ('static_partitions' = 'true') AS SELECT production_line, defect_month, COUNT(*) AS total_defects, SUM(is_critical) AS critical_defects, ROUND(SUM(is_critical)*100.0/COUNT(*), 2) AS critical_rate_pct, ROUND(SUM(repair_cost), 2) AS total_repair_cost, ROUND(AVG(repair_cost), 2) AS avg_repair_cost, COUNT(DISTINCT product_id) AS affected_products FROM best_practice_manufacturing_spc.silver_defect_enriched GROUP BY production_line, defect_month;

手动触发首次刷新:

REFRESH DYNAMIC TABLE best_practice_manufacturing_spc.gold_production_line_monthly;

查看 Line-3 月度趋势(Critical 比率波动较大的生产线):

SELECT production_line, defect_month, total_defects, critical_rate_pct, total_repair_cost FROM best_practice_manufacturing_spc.gold_production_line_monthly WHERE production_line = 'Line-3' ORDER BY defect_month;

production_line | defect_month | total_defects | critical_rate_pct | total_repair_cost ----------------+---------------------+---------------+-------------------+----------------- Line-3 | 2024-01-01T00:00:00 | 86 | 38.37 | 43501.08 Line-3 | 2024-02-01T00:00:00 | 49 | 44.90 | 24149.23 Line-3 | 2024-03-01T00:00:00 | 60 | 25.00 | 31843.13 Line-3 | 2024-04-01T00:00:00 | 45 | 48.89 | 23162.77 Line-3 | 2024-05-01T00:00:00 | 61 | 26.23 | 32361.05 Line-3 | 2024-06-01T00:00:00 | 47 | 25.53 | 26731.13

结果解读:Line-3 的 1 月缺陷数最高(86 条),但 Critical 比率(38.37%)并非全期最高——4 月 Critical 比率达到 48.89%,但缺陷总数较低(45 条)。这种"批次小但严重程度高"的模式提示可能存在原材料批次问题,需结合

product_id
product_id
维度进一步追溯。


Gold 层 Dynamic Table:缺陷 Pareto 分析

Pareto 分析基于"80/20 法则",识别造成主要缺陷成本的少数根因类别。

CREATE DYNAMIC TABLE IF NOT EXISTS best_practice_manufacturing_spc.gold_defect_pareto REFRESH INTERVAL 10 MINUTE VCLUSTER DEFAULT AS SELECT defect_type, severity, defect_location, COUNT(*) AS defect_count, ROUND(SUM(repair_cost), 2) AS total_repair_cost, ROUND(COUNT(*)*100.0 / SUM(COUNT(*)) OVER (), 2) AS defect_pct, SUM(COUNT(*)) OVER ( ORDER BY COUNT(*) DESC ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) AS cumulative_count, ROUND(SUM(COUNT(*)) OVER ( ORDER BY COUNT(*) DESC ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) * 100.0 / SUM(COUNT(*)) OVER (), 2) AS cumulative_pct FROM best_practice_manufacturing_spc.silver_defect_enriched GROUP BY defect_type, severity, defect_location ORDER BY defect_count DESC;

手动触发首次刷新:

REFRESH DYNAMIC TABLE best_practice_manufacturing_spc.gold_defect_pareto;

查看 Top 10 缺陷类别(按数量降序,含累计百分比):

SELECT defect_type, severity, defect_location, defect_count, total_repair_cost, defect_pct, cumulative_pct FROM best_practice_manufacturing_spc.gold_defect_pareto ORDER BY defect_count DESC LIMIT 10;

defect_type | severity | defect_location | defect_count | total_repair_cost | defect_pct | cumulative_pct ------------+----------+-----------------+--------------+-------------------+------------+--------------- Structural | Minor | Surface | 51 | 25935.06 | 5.10 | 5.10 Structural | Critical | Surface | 46 | 21754.09 | 4.60 | 9.70 Structural | Minor | Internal | 44 | 25146.07 | 4.40 | 22.90 Structural | Minor | Component | 44 | 22656.89 | 4.40 | 14.10 Functional | Critical | Internal | 44 | 22739.99 | 4.40 | 18.50 Functional | Moderate | Component | 41 | 21378.39 | 4.10 | 27.00 Cosmetic | Moderate | Surface | 40 | 18387.07 | 4.00 | 31.00 Functional | Critical | Component | 39 | 23047.16 | 3.90 | 38.80 Cosmetic | Minor | Surface | 39 | 19181.07 | 3.90 | 34.90 Functional | Minor | Surface | 38 | 18227.96 | 3.80 | 42.60

结果解读:Top 10 类别累计占总缺陷数的 42.60%,其中表面(Surface)位置的结构类(Structural)缺陷最多,但若按修复费用排序,

Functional × Critical × Component
Functional × Critical × Component
(39 条,总费用 23,047 元)的单件费用最高(591 元/件)。Pareto 治理优先级建议:先攻 Surface 上的 Structural Minor 缺陷(数量最多),再攻 Component 上的 Functional Critical 缺陷(单件费用最高)。

查看三大缺陷类型总量对比:

SELECT defect_type, SUM(defect_count) AS total, ROUND(SUM(total_repair_cost), 2) AS total_cost FROM best_practice_manufacturing_spc.gold_defect_pareto GROUP BY defect_type ORDER BY total DESC;

defect_type | total | total_cost ------------+-------+----------- Structural | 352 | 176923.85 Functional | 339 | 171905.58 Cosmetic | 309 | 158797.72


PPM 缺陷率计算

PPM(Parts Per Million)衡量百万分之缺陷数,是 SPC 和六西格玛体系的标准化质量指标:

SELECT defect_type, COUNT(*) AS defect_count, ROUND(COUNT(*) * 1000000.0 / 1000, 0) AS ppm_rate FROM best_practice_manufacturing_spc.doc_defect_events GROUP BY defect_type ORDER BY ppm_rate DESC;

defect_type | defect_count | ppm_rate ------------+--------------+--------- Structural | 352 | 352000 Functional | 339 | 339000 Cosmetic | 309 | 309000

结果解读:三类缺陷的 PPM 均在 30 万以上,对应 σ 水平约为 2σ(六西格玛目标为 3.4 PPM,即 6σ)。这是数据集的特征——1,000 件中 1,000 件有缺陷,实际使用时分母应为总检测件数(含合格品)。


Studio 刷新任务配置

Dynamic Table 的定期刷新通过 Studio Task 调度,可在同一任务上附加监控告警和数据质量检查规则。

以下用

cz-cli task
cz-cli task
命令创建刷新任务(等同于在 Studio 界面操作):

# 1. 创建任务文件夹 cz-cli task create-folder "manufacturing_spc" --parent 186117 -p skill_test # 返回:{"data":187106} ← 记录 folder id # 2. 创建 Silver 层刷新任务 cz-cli task create "refresh_silver_defect_enriched" \ --type SQL --folder 187106 -p skill_test # 返回:{"data":{"id":10354655, ...}} # 3. 写入刷新 SQL cz-cli task save-content "refresh_silver_defect_enriched" \ --content "REFRESH DYNAMIC TABLE best_practice_manufacturing_spc.silver_defect_enriched;" \ -p skill_test # 4. 配置 Cron 调度(每 10 分钟) cz-cli task save-cron "refresh_silver_defect_enriched" \ --cron "*/10 * * * *" -p skill_test # 5. 创建 Gold 层刷新任务(同上) cz-cli task create "refresh_gold_production_line_monthly" \ --type SQL --folder 187106 -p skill_test cz-cli task save-content "refresh_gold_production_line_monthly" \ --content "REFRESH DYNAMIC TABLE best_practice_manufacturing_spc.gold_production_line_monthly;" \ -p skill_test cz-cli task save-cron "refresh_gold_production_line_monthly" \ --cron "*/10 * * * *" -p skill_test

任务创建完成后,在 Studio 界面的

best_practices/manufacturing_spc/
best_practices/manufacturing_spc/
路径下可看到两个刷新任务。点击任务 → 告警配置,可绑定"刷新失败通知"或"数据行数为 0 告警"等规则。任务就绪后发布上线:

cz-cli task deploy "refresh_silver_defect_enriched" -p skill_test cz-cli task deploy "refresh_gold_production_line_monthly" -p skill_test


数仓对象总览

SHOW TABLES IN best_practice_manufacturing_spc;

schema_name | table_name | is_dynamic -----------------------------------+---------------------------------+----------- best_practice_manufacturing_spc | doc_defect_events | false best_practice_manufacturing_spc | doc_product_master | false best_practice_manufacturing_spc | silver_defect_enriched | true best_practice_manufacturing_spc | gold_production_line_monthly | true best_practice_manufacturing_spc | gold_defect_pareto | true

数据流概览:

MES System(Kafka) Manual Sampling(CSV) │ │ ▼ Kafka PIPE(60s batch) ▼ COPY INTO(Volume) kafka_raw_defects doc_defect_events(Bronze) │ Bloomfilter Index(product_id) doc_product_master ────┤ LEFT JOIN (production_line │ UCL / LCL / spec_target) │ ▼ Studio Task: refresh every 10 min silver_defect_enriched(Dynamic Table) severity_score UDF · is_critical · defect_month │ │ ┌─────────────────┘ └──────────────────┐ ▼ Studio Task: refresh every 10 min ▼ gold_production_line_monthly(DT) gold_defect_pareto(DT) PARTITIONED BY production_line cumulative_pct(Pareto 80%) static_partitions = true Window Function ORDER BY │ │ ▼ ▼ Quality Dashboard Root Cause Analysis Cpk · UCL/LCL 80/20 Defect Focus


注意事项

  • 窗口函数不支持二层聚合嵌套

    STDDEV_SAMP(COUNT(*)) OVER (...)
    STDDEV_SAMP(COUNT(*)) OVER (...)
    这类在窗口函数中嵌套聚合函数的写法会报"aggregate function cannot contain another aggregate function"错误。正确做法是先用 CTE 完成
    GROUP BY
    GROUP BY
    聚合,再在外层对结果列应用窗口函数。

  • 分区 Dynamic Table 必须声明 static_partitions

    PARTITIONED BY
    PARTITIONED BY
    的 DT 必须设置
    TBLPROPERTIES ('static_partitions' = 'true')
    TBLPROPERTIES ('static_partitions' = 'true')
    。不声明时系统使用动态分区推断,在增量刷新时可能导致旧分区数据被覆盖或丢失。

  • Bloomfilter Index 对存量数据不自动生效

    CREATE BLOOMFILTER INDEX
    CREATE BLOOMFILTER INDEX
    只对创建后写入的新数据生效,不支持
    BUILD INDEX
    BUILD INDEX
    覆盖存量数据(BLOOMFILTER 类型无此能力,如需覆盖存量需重建表)。

  • Dynamic Table 的刷新调度通过 Studio Task 管理:不要依赖 DDL 中的

    REFRESH INTERVAL
    REFRESH INTERVAL
    做生产调度,而是在 Studio Task 中配置 Cron,这样可以在同一任务上绑定告警规则和数据质量检查,实现统一的可观测性。

  • PPM 计算中分母的选取:文中演示 PPM 以 1,000 条检测记录为分母,仅供说明。生产环境中,PPM 的分母应为总检测件数(含合格品),通常来自 MES 系统的生产完工报工数据,需额外建表关联。

  • Cpk 中 std_val = 0 的处理

    calc_cpk
    calc_cpk
    UDF 在
    std_val <= 0
    std_val <= 0
    时返回 NULL,避免除零错误。这种情况出现在样本量为 1 时,Gold 层聚合前应过滤掉样本量不足的分组(
    HAVING COUNT(*) > 1
    HAVING COUNT(*) > 1
    )。


相关文档

联系我们
预约咨询
微信咨询
电话咨询
邮件咨询