枚举与范围校验是什么
枚举校验维护一份合法取值字典(状态、渠道、支付方式、币种),范围校验按业务定义上下限(金额非负、折扣率在 0 到 1、年龄在合理区间)。这两类规则判定标准客观、可完全自动化,因此适合做成可配置的校验项:字典与阈值集中维护,而不是散写在每条 SQL 里。规则可配置化之后,业务新增枚举值只需更新字典,不用改代码,也能避免「改了这里忘了那里」。
基本信息
| 枚举字典 | 状态、渠道、支付方式、币种等取值集合,按表与字段维护 |
|---|---|
| 范围定义 | 取值下限、上限以及区间开闭,按业务规则确定 |
| 执行频率 | 每日例行稽核,加上上游变更后的临时校验 |
| 输出 | 字典外取值清单、越界行数与影响范围,落稽核表保留历史 |
| 字典维护 | 与业务系统的枚举表对齐,更新需有评审记录 |
| 空值处理 | 空值需单独判定,不能与非法取值混在一处统计 |
典型使用场景
- 源端新增状态码:枚举字典未同步时立即发现并推动更新字典
- 金额负值排查:出现负的支付金额或折扣金额,直接定位异常分区
- 折扣与比例校验:折扣率超出 0 到 1 的区间,通常意味着单位或换算错误
- 币种校验:多币种场景下出现字典外币种,避免折算逻辑取到默认值
- 变更回归:上游加字段或改类型后复跑同一套规则确认无回归
字典外取值清单
字典外取值清单
-- 列出不在字典中的取值及其影响行数
SELECT status_name, COUNT(1) AS cnt
FROM dwd_trade_order_detail_di
WHERE dt = '2026-10-11'
AND status_name NOT IN ('created','paid','shipped','closed','refunded')
GROUP BY status_name
ORDER BY cnt DESC;
-- 与字典表比对更稳妥:字典更新后无需改 SQL
SELECT DISTINCT d.status_name, COUNT(1) AS cnt
FROM dwd_trade_order_detail_di d
LEFT JOIN dim_order_status_dict c ON d.status_name = c.status_name
WHERE d.dt = '2026-10-11' AND c.status_name IS NULL
GROUP BY d.status_name;范围校验
范围校验
-- 越界行数:金额非负、折扣比例在 0 到 1 之间
SELECT COUNT(1) AS out_of_range,
SUM(CASE WHEN discount_rate < 0 OR discount_rate > 1 THEN 1 ELSE 0 END) AS bad_rate,
SUM(CASE WHEN discount_amt < 0 THEN 1 ELSE 0 END) AS neg_amt
FROM dwd_trade_discount_di
WHERE dt = '2026-10-11'
AND (discount_rate < 0 OR discount_rate > 1 OR discount_amt < 0);
-- 阈值应来自配置表,而不是写死在 SQL 里
-- SELECT field_name, min_value, max_value, allow_null FROM dq_rule_config;规则类型与判定
| 规则 | 判定方式 | 异常含义 |
|---|---|---|
| 枚举 | 取值是否在字典集合内 | 字典外值,通常是源端新增或映射遗漏 |
| 范围下限 | 取值不小于下限 | 负数金额,多为符号或计算错误 |
| 范围上限 | 取值不大于上限 | 比例超 1,多为单位或小数位错误 |
| 区间开闭 | 边界值是否允许 | 边界处理与业务约定不符 |
| 空值 | 是否允许为空 | 空值口径与范围判定混用会掩盖问题 |
枚举字典与业务系统的枚举表对齐后可以自动同步,能有效避免手工维护滞后;字典更新要有评审记录,否则规则失效时无法追溯是哪次变更导致的。
NOT IN 遇到 NULL 时判定结果为未知,空值行会被静默排除,导致空值比例被低估;枚举校验与空值校验要分开统计,别让两类问题互相掩盖。