Files
opencode-build/skills/sql-review/SKILL.md
T
2026-07-01 17:46:08 +08:00

117 lines
4.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
name: sql-review
description: 当一条 Spark SQL 已经生成、通过 guardrails 并准备展示或执行前使用。它基于 sql_context 静态检查字段引用、alias、join key、数据膨胀、重复聚合、时间过滤、转化顺序、GROUP BY、空值、类型和写入风险,只报告问题,不直接改 SQL。
---
# SQL ReviewSQL 静态评审)
## 目标
在 SQL 执行前做质量检查,发现可能导致数字错误、执行失败或性能风险的问题。评审只报告风险和建议,不负责直接改写 SQL。
## 输入
```yaml
sql: "待评审的 Spark SQL"
sql_context:
status: CONTEXT_READY
sql_guard:
status: PASS
logic_plan:
status: PLANNED
```
如果没有 `sql_context`,也可以继续做基础结构检查,但必须报告一个 HIGH 风险:缺少上下文,无法保证字段和 join 正确。
## 检查项
1. 字段引用:每个 `alias.column` 是否存在于 `sql_context.fields`
2. aliasSQL 是否发明了 context 中没有的 alias。
3. join keyON 条件是否匹配 context 中固定的 join。
4. join 基数:1:N 或 N:N join 是否会造成数据膨胀。
5. 指标公式:聚合表达式是否符合 logic plan 和 context。
6. 重复聚合:同一指标是否被重复 sum/count。
7. 时间过滤:事实表是否缺少必要时间或分区过滤。
8. 时间边界:T-1 完整日是否使用左闭右开窗口。
9. 转化顺序:后置事件是否满足前置事件之后发生。
10. GROUP BY:非聚合输出列是否都在 group by 中。
11. 空值策略:join key 和度量字段是否需要 coalesce 或保留策略。
12. 类型匹配:字符串日期、字符串金额是否需要 cast。
13. 写入风险:INSERT 目标列、overwrite 确认、分区覆盖范围是否明确。
14. 执行成本:是否存在无分区裁剪的大表全扫、笛卡尔积、窗口无 partition。
## 时间边界检查
当需求为“近 N 天按 T-1 完整日”且字段是 timestamp/date-like
推荐:
```sql
event_time >= date_sub(current_date(), N)
AND event_time < current_date()
```
风险写法:
```sql
event_time BETWEEN date_add(current_date(), -N) AND date_add(current_date(), -1)
```
如果 SQL 使用风险写法,至少标为 `MEDIUM`;如果会明显漏掉结束日期白天数据,标为 `HIGH`
## 转化顺序检查
对注册、付费、激活、下单等漏斗指标,必须检查后置事件是否在前置事件之后。若口径是“注册后付费”,SQL 必须有等价约束:
```sql
pay_time >= register_time
```
如果 SQL 先按用户取 `MIN(pay_time)`,再和 `register_time` 比较,而没有在聚合前加入 `pay_time >= register_time`,标为 `HIGH``MEDIUM`,因为这可能漏算注册后仍然完成付费的用户。
## 输出格式
```yaml
sql_review:
verdict: PASS | FAIL
highest_severity: NONE | LOW | MEDIUM | HIGH
summary: "一句话结论"
findings:
- id: R1
severity: HIGH | MEDIUM | LOW
check: reference_integrity | join_cardinality | metric_formula | time_filter | time_boundary | conversion_order | group_by | type_check | write_risk | performance | other
location: "SQL 片段或行号"
message: "问题描述"
recommendation: "建议修复方向"
notes:
- "评审假设"
```
## 用户可见摘要
除了 YAML,必须输出:
```markdown
## SQL Review
- 结论:PASS / FAIL
- 最高风险:NONE / LOW / MEDIUM / HIGH
- 已检查:字段引用、join、GROUP BY、时间窗口、转化顺序、空值、类型、性能
- 主要风险:...
- 是否可交付:...
```
## 严重程度
- `HIGH`:会导致数字错误、执行失败、越权写入或违反策略,必须阻断。
- `MEDIUM`:大概率可跑,但有性能、稳定性或边界风险,需要用户接受。
- `LOW`:风格或可维护性问题。
只要存在 HIGH`verdict` 就是 `FAIL`。只有 LOW/MEDIUM 时,可以把风险交给用户决定是否接受。
## 禁止行为
- 不要直接改 SQL;只输出发现和建议。
- 不要凭直觉审字段,必须对照 `sql_context`
- 不要因为 SQL 能通过 guardrails 就跳过业务正确性审查。
- 不要忽略写入模式,尤其是 `INSERT OVERWRITE`