3. SQL 聚合查询基础回顾:GROUP BY、HAVING、聚合函数在批次场景下的行为

在授信决策引擎的批次偏移分析中,SQL 聚合查询是定位数据差异的核心工具。批次偏移的本质是“同一业务逻辑在不同时间窗口或不同批次间,聚合结果不一致”。因此,深入理解 GROUP BY、HAVING 以及 SUM、COUNT、AVG 等聚合函数在批次数据下的执行行为,是诊断偏移问题的第一步。

3.1 聚合函数在批次场景下的行为差异

聚合函数对一组行执行计算并返回单个值。在批次偏移场景中,最常出现的问题源于聚合函数对 NULL 值、重复记录 以及 边界时间戳 的处理差异。

聚合函数 批次场景常见陷阱 偏移影响
SUM(column) 忽略 NULL;若批次内存在重复主键,金额被重复加总 授信额度虚高或虚低
COUNT(*) vs COUNT(column) COUNT(*) 包含 NULL 行;COUNT(column) 跳过 NULL 批次记录数统计偏差
AVG(column) 受极端值影响大;批次间数据分布变化导致均值漂移 评分卡阈值失效
MAX/MIN(column) 批次边界时间戳截断导致极值丢失 逾期天数计算错误
批次偏移案例: 某风控系统在 T 日跑批时使用 COUNT(apply_id) 统计进件量,但部分 apply_id 为 NULL 的测试记录未被计入,导致与业务报表偏差 2.3%。修正为 COUNT(*) 后对齐。

3.2 GROUP BY 的分组逻辑与批次偏移

GROUP BY 将查询结果按一列或多列分组,然后对每个组应用聚合函数。在批次偏移定位中,GROUP BY 的 分组键选择 直接决定偏移能否被暴露。

  • 按批次标识分组: 使用 batch_id 或 run_date 作为分组键,对比不同批次的聚合结果。
  • 按业务维度分组: 如 product_type、channel,发现某个维度的偏移被全局聚合掩盖。
  • 多列分组顺序: 在批次偏移对比中,GROUP BY batch_id, product_type 与 GROUP BY product_type, batch_id 结果相同,但执行计划可能不同。
-- 批次偏移对比查询:按批次和产品类型聚合
SELECT
    batch_id,
    product_type,
    COUNT(*)          AS apply_cnt,
    SUM(loan_amount)  AS total_loan,
    AVG(risk_score)   AS avg_risk
FROM decision_engine.credit_apply
WHERE run_date BETWEEN '2025-01-01' AND '2025-01-31'
GROUP BY batch_id, product_type
ORDER BY batch_id, product_type;
偏移定位技巧: 当怀疑批次偏移时,先使用 GROUP BY batch_id 做粗粒度对比,若发现差异,再逐层下钻到 GROUP BY batch_id, channel, product_type 等细粒度分组,定位偏移源头。

3.3 HAVING 在批次过滤中的特殊作用

HAVING 用于过滤分组后的聚合结果,与 WHERE 在分组前过滤不同。在批次偏移分析中,HAVING 常用于筛选出“异常批次”。

过滤阶段 关键字 批次偏移场景示例
分组前 WHERE 过滤掉测试批次、无效记录
分组后 HAVING 筛选出聚合结果偏离阈值的批次
-- 使用 HAVING 定位偏移批次:找出平均风险分偏离超过 10% 的批次
SELECT
    batch_id,
    COUNT(*)          AS record_cnt,
    AVG(risk_score)   AS avg_risk,
    STDDEV(risk_score) AS std_risk
FROM decision_engine.credit_apply
WHERE run_date >= '2025-01-01'
GROUP BY batch_id
HAVING ABS(AVG(risk_score) - 650) > 65   -- 假设基准均值为 650
   OR COUNT(*) < 1000;                     -- 批次记录数异常少
性能警告: HAVING 在分组完成后执行过滤,无法利用索引。对于大表批次对比,建议先用 WHERE 缩小数据范围,再用 HAVING 做聚合后过滤,避免全表分组带来的性能开销。

3.4 聚合查询在批次偏移中的执行流程

理解 SQL 聚合查询的执行顺序,有助于在批次偏移分析中快速定位是“数据问题”还是“查询逻辑问题”。

  1. FROM + JOIN: 确定数据源,关联多表(如申请主表 + 拒绝原因表)。
  2. WHERE: 过滤非目标批次、无效数据。
  3. GROUP BY: 按分组键将数据划分为多个逻辑桶。
  4. 聚合函数计算: 在每个桶内执行 SUM/COUNT/AVG。
  5. HAVING: 过滤掉不符合条件的聚合结果。
  6. SELECT + ORDER BY: 输出最终结果并排序。
SQL 聚合查询执行流程(批次偏移分析视角) 1. FROM / JOIN 关联申请、拒绝、征信表 2. WHERE 过滤测试批次、无效记录 3. GROUP BY 按 batch_id 分组 4. 聚合函数 SUM / COUNT / AVG 5. HAVING 过滤异常批次 6. SELECT / ORDER BY 批次偏移关键检查点 • WHERE 是否误过滤了有效批次? • GROUP BY 键是否包含重复主键? • HAVING 阈值是否合理?

3.5 批次偏移聚合查询的常见反模式

在授信决策引擎的批次偏移排查中,以下三种聚合查询反模式最容易导致误判:

反模式 错误写法示例 偏移后果 正确做法
忽略 NULL 的 COUNT COUNT(risk_score) 漏计 NULL 风险分记录,批次统计量偏小 COUNT(*) 或 COALESCE(risk_score,0)
GROUP BY 键不唯一 GROUP BY batch_id 但同一 batch_id 内主键重复 聚合结果被重复记录放大 先 DISTINCT 去重或使用窗口函数
HAVING 与 WHERE 混用 用 WHERE AVG(score) > 600 语法错误或逻辑错误 聚合后过滤必须用 HAVING
实战建议: 在编写批次偏移对比查询时,始终先执行 SELECT batch_id, COUNT(*) AS cnt FROM ... GROUP BY batch_id 确认各批次记录数是否合理,再逐步加入金额、评分等聚合字段。这个“记录数先行”的习惯能快速排除大部分数据源问题。