# 09 · 39 个 V1 ETL 索引清单（附录）

> 本附录是**索引层**，不是公式手册。当你在 [01~07](README.md) 公式 / [08 章范式](08-etl-engineering-patterns.md)里找不到对应内容时，回这里**按业务域定位原 ETL 文件**，去**本地 V1 ETL JSON 目录**抓完整 JSON。
>
> **说明**：本清单 ETL 名称已脱敏（去掉个人/品牌后缀），实际本地文件名可能带个人标识后缀（如 `—xxx`）。引用本地文件时按你方实际命名调整。

## 全局画像

- **总数**：39 个 ETL
- **节点总量**：~590 节点（平均 15 节点/ETL，中位数 11，最大 48）
- **节点类型分布**（按出现 ETL 数）：GROUP_BY (35) > INPUT_DATASET (35) > OUTPUT_DATASET (39) > JOIN_DATA (29) > FILTER_ROWS (24) > CALCULATOR (20) > SQL_SCRIPT (18) > APPEND_ROWS (10) > SELECT_COLUMNS (1)
- **SQL_SCRIPT 节点最多的 ETL**：RFM 顾客分层 (9 个 SQL_SCRIPT) — 单维度算法用 SQL，组装用节点
- **INPUT_DATASET 最多的 ETL**：券明细 (11 个 input) — 营销活动数据 11 张表汇拢
- **体量最大的 ETL**：券明细 (48 节点) — 重节点轻 SQL 流派代表
- **体量最小的 ETL**：日期维度表、90 天未消费、CRM 订单表（3~4 节点）— 轻量公式封装

## 业务域分类索引

11 个业务域，每域开头一句话定位，后跟该域 ETL 速查表。

---

### A. 基础维表层（5 个）

> 所有下游 ETL 的"地基"。改这里的字段，下游全要回归测试。

| ETL | 节点 | 输入 | 输出 | SQL 节点 | 价值点 |
|---|---:|---|---|---|---|
| **日期维度表** | 3 | 日期 | 日期维度表 | — | 最小可用维度表，含周/月/季/年衍生列 |
| 日期&门店组合表 | 11 | 日期维度表 + 门店信息 | 日期&门店组合表 | — | Cohort 笛卡尔积网格 |
| **门店信息** | 40 | 8 张门店相关源表 + DWS 财务 | 门店信息（主数据）| 2 SQL | 主数据治理，[范式 2 重节点流派](08-etl-engineering-patterns.md#范式-2轻节点重-sql-vs-重节点轻-sql-工程哲学)代表 |
| 门店支付通道 | 8 | 门店订单支付通道信息 | 门店支付通道 | 1 SQL | DWD 宽表的支付维表 |
| user_卡号对应 | 8 | tb_user_channel + tb_card_info | user_卡号对应 | — | 顾客标识跨渠道映射的基础维表 |

---

### B. 订单事实 / DWD（3 个）

> 所有营收 / KPI / 复购的事实源。

| ETL | 节点 | 输入 | 输出 | SQL 节点 | 价值点 |
|---|---:|---|---|---|---|
| **DWD_订单明细宽表** | 8 | 6 张维表 (订单 + 门店 + 支付 + user + 卡 + 用户) | DWD 宽表 | 1 SQL_CTE | 🔴 [10-CTE 范式样本](08-etl-engineering-patterns.md#dwd-cte-范式)；昨日测试 v3，已对齐观远 SQL 中文别名 |
| **订单明细** | 32 | 5 张订单与维表 | 订单明细 | 1 SQL | 32 节点的"重节点轻 SQL"风格，作为 DWD 的扩展型范例 |
| 订单产品 | 8 | 外卖产品分类映射 + 订单明细 | 订单产品 | 1 SQL | 订单 ↔ 商品归类（SKU 维度） |

> **DWD 宽表 vs 订单明细 的工程取舍对比**：
> - DWD 宽表 8 节点，1 个超长 SQL_CTE — **轻节点重 SQL**
> - 订单明细 32 节点，1 个轻量 SQL — **重节点轻 SQL**
> - 两者都跑同一类事实，只是工程风格不同。见 [08 章 · 范式 2](08-etl-engineering-patterns.md#范式-2轻节点重-sql-vs-重节点轻-sql-工程哲学)

---

### C. 会员档案 / 顾客 ID（4 个）

> 客户主数据治理。顾客标识 ETL 是这里的核心（43 节点，跨多源 ODS）。

| ETL | 节点 | 输入 | 输出 | SQL 节点 | 价值点 |
|---|---:|---|---|---|---|
| **顾客标识** | 43 | 9 张表 (5 个月度 ODS + 门店 + 会员 + user 卡号 + 补齐) | 顾客流失 + 堂食顾客标识 + 新老客 (3 输出) | 3 SQL | 🔴 跨多月 ODS 串联，3 输出聚合；包含 [02 章 R 三档分级](02-customer-and-membership.md#r-阈值多档分级按业务场景调) 来源 |
| 会员表 | 26 | 5 表 (好友 + openid + 卡 + 用户 + 注册首单) | 会员信息 | — | 会员主数据归集 |
| **会员注册/首单/最后门店** | 27 | 4 表 (门店 + 会员 + 订单) | 会员注册/首单/最后门店 | 2 SQL | 🔴 [04 章注册门店清洗](04-channel-and-store.md#注册门店清洗优先级回填-) 的 ETL 实现，含归属优先级回填 |
| 微信小程序会员注册 | 12 | 3 表 (门店 + 会员) | 微信小程序会员注册 | — | 渠道维度 — 小程序注册路径 |

---

### D. 顾客行为分层 / RFM / 复购 / 流失（5 个）

> 这一组是公式库 [02 章](02-customer-and-membership.md) 的主要来源。

| ETL | 节点 | 输入 | 输出 | SQL 节点 | 价值点 |
|---|---:|---|---|---|---|
| **RFM 顾客分层** | 19 | 堂食顾客标识 | RFM 顾客分层 | 9 SQL | 🔴 9 个 SQL_SCRIPT 拆 R/F/M 单维度计算；[02 章 8 类×营销策略](02-customer-and-membership.md#rfm-8-类--营销策略对应生产-etl-加强版) 来源 |
| 90 天未消费 | 3 | 堂食顾客标识 | 90 天未消费 | 1 SQL | 最简公式 ETL — 输入直接 SQL 加工后输出 |
| 近 30 天复购 | 5 | 堂食顾客标识 | 近 30 天复购 | 2 SQL | "筛选近 30 天" + "复购计算" 两段 SQL 串联 |
| 注册前后订单 | 7 | 堂食顾客标识 | 注册前后分析 + 注册前后订单 (2 输出) | 2 SQL | doc 2 那段 4 层 CTE 的 ETL 化版本 |
| 门店新老客明细 | 9 | 新老客 | 门店新老客明细 | — | 顾客标识下游 — 按门店维度聚合 |

---

### E. 财务与营收（3 个）

> 营业额口径敏感区，建议配合 [范式 3 双源对账](08-etl-engineering-patterns.md#范式-3财务双源对账-) 使用。

| ETL | 节点 | 输入 | 输出 | SQL 节点 | 价值点 |
|---|---:|---|---|---|---|
| CRM 订单表 | 4 | tb_order_log 订单日志 | CRM 订单表 | — | 最简事实表 — 1 计算列 + 聚合 |
| DWS 财务订单表 | 15 | 4 表 (门店编码 + 门店 + 财务) | DWS 财务订单表 | — | 财务侧主表，下游被双源对账 ETL 引用 |
| 门店订单明细 | 17 | 会员信息 + 订单明细 | 门店订单明细 | 1 SQL | 订单 × 门店 聚合表 |

---

### F. 营销目标 / 拉新（3 个）

| ETL | 节点 | 输入 | 输出 | SQL 节点 | 价值点 |
|---|---:|---|---|---|---|
| 拉新门店数占比 | 7 | 门店信息 + 微信小程序会员注册 | 拉新门店数占比 | — | 渠道拉新覆盖率指标 |
| 会员标杆门店 | 11 | 订单明细 + 会员信息 | 会员标杆门店 | — | 会员表现 Top 门店筛选 |
| 会员蓄水目标达成 | 9 | 分公司蓄水目标 + 拉新门店数占比 | 会员蓄水目标达成 | — | 目标完成率指标，含目标 dim 表 |

---

### G. 私域社群 / 好友 / 群（4 个）

> 企微社群运营全套，下游是社群留存/流失分析。

| ETL | 节点 | 输入 | 输出 | SQL 节点 | 价值点 |
|---|---:|---|---|---|---|
| **好友数据** | 31 | 7 表 (门店 + 渠道活码 + 好友 + 群成员 + 群 + 会员 + 群列表) | 企微好友明细 + 熟客群废弃 (2 输出) | — | 私域数据归一化整合 |
| 门店好友明细 | 16 | 日期&门店组合表 + 企微好友明细 | 门店好友明细 | 1 SQL（节点名"留存好友"）| 留存计算 — 日期×门店 cohort + 累计窗口 |
| 熟客群明细 | 17 | 5 表 (门店 + 好友 + 群成员 + 会员 + 群) | 熟客群明细 | — | 群成员归属 + 标签聚合 |
| 群标签 | 21 | 3 表 (门店 + 群 + 群标签) | 群列表 | — | 群 ↔ 标签多对多聚合（用 [06 章 collect_set+concat_ws](06-sql-utils.md#collect_set--concat_ws多行聚一列-)）|

---

### H. 营销活动 / 券 / 抽奖 / 积分（4 个）

| ETL | 节点 | 输入 | 输出 | SQL 节点 | 价值点 |
|---|---:|---|---|---|---|
| **券明细** | **48** | 11 表 (门店 + 券类型 + 券明细 + 订单 + 会员 + 过期券 + 活动汇总) | 测试券明细 + 券明细 (2 输出) | — | 🔴 全集最大体量，**重节点轻 SQL 流派代表**（12 GROUP_BY + 11 JOIN_DATA + 0 SQL_SCRIPT）|
| 会员抽奖活动 | 11 | 抽奖日志 + 会员信息 | 会员抽奖活动 | — | 活动维度事实 |
| 会员抽奖聚合 | 23 | 抽奖活动 + 活动自煮包发放 | 抽奖自煮包库存明细 + 会员抽奖聚合 (2 输出) | 2 SQL | 自煮包库存对账 |
| 积分兑换 | 6 | 会员信息 + 积分商城 | 积分兑换 | — | 积分商城兑换事实 |

> **券明细为什么没用 SQL_SCRIPT？**
> 营销活动逻辑频繁变动（券类型加新、活动规则调整），48 节点的可视化拓扑让运营/营销同学**点开就能看清"哪条规则触发哪个分支"**，调整时连线改一改即可。如果用大 SQL，每次改动都要找 BI 工程师 review SQL diff，反应速度慢一截。

---

### I. 评价管理（5 个）

> [04 章 · 多渠道评价 Pipeline](04-channel-and-store.md#多渠道评价pipeline) 的完整 ETL 实例。

| ETL | 节点 | 输入 | 输出 | SQL 节点 | 价值点 |
|---|---:|---|---|---|---|
| 堂食评价 | 19 | 3 表 (打卡 + 订单评价 + 订单明细) | 堂食评价 | 1 SQL（标签聚合）| 打卡+订单双源 JOIN 模式 |
| 美团评价 | 12 | 2025 美团 + 2026 美团 + 门店信息 | 美团评价 | 1 SQL（图片字段 split 拆 9 列）| 跨年 APPEND_ROWS 串联模式 |
| 饿了么评价 | 13 | 2025 饿了么 + 2026 饿了么 + 门店信息 | 饿了么评价 | 1 SQL（图片字段 from_json + element_at 拆 9 列）| 同上但 JSON 数组格式 |
| 美饿外卖评分 | 15 | 美团评分 25/26 + 饿了么评分 25/26 + 门店信息 | 美饿外卖评分 | — | 4 平台×2 年评分数据合并 |
| **外卖评价分类** | 14 | 美团评价 + 饿了么评价 | 外卖评价原始数据 + 外卖评价分类—优化 (2 输出) | 1 SQL（超长正则分类，~250 行）| 🔴 评价情绪打标总聚合，[04 章 § 评价分类](04-channel-and-store.md#评价分类情绪--标签-) 来源 |

---

### J. 业务字段标签（1 个）

| ETL | 节点 | 输入 | 输出 | SQL 节点 | 价值点 |
|---|---:|---|---|---|---|
| 商品风味分类 | 8 | 订单明细 | 商品风味分类 | — | 商品名 → 口味分类的纯计算列 ETL（15 类口味，CALCULATOR 节点链）|

---

### K. 数据质量监控（2 个）

> [范式 3 双源对账](08-etl-engineering-patterns.md#范式-3财务双源对账-) 的来源。

| ETL | 节点 | 输入 | 输出 | SQL 节点 | 价值点 |
|---|---:|---|---|---|---|
| **财务表异常门店** | 17 | 3 表 (DWD 总计财务 + DWD 总计 + DWS 财务订单表) | 财务表异常门店 + 一个编号多个名字 (2 输出) | — | 🔴 [范式 3 双源对账](08-etl-engineering-patterns.md#范式-3财务双源对账-)的实战来源 |
| **多 POS 系统门店编号追踪** | 21 | 5 表 (门店 + 订单中心门店 + 公共门店主表 + POS_C 系统 + POS_D 门店) | 多 POS 编号追踪 + 门店编号明细 (2 输出) | 1 SQL | 5 个 POS 系统的门店编号一致性校验，[范式 4 POS 归一化](08-etl-engineering-patterns.md#范式-4pos-系统识别--渠道归一化-) 来源 |

---

## 复用决策表

| 你想做的事 | 直接抄哪个 ETL 当模板 |
|---|---|
| 写 DWD 宽表底座 | DWD_订单明细宽表 (8 节点 + 10-CTE) |
| 多源 ODS 串联 | 顾客标识 (43 节点，9 个 ODS 月度表 APPEND) |
| RFM 顾客分层 | RFM 顾客分层 (19 节点，9 SQL 单维度) |
| 私域好友数据归一 | 好友数据 (31 节点) |
| 多平台评价整合 | 美团评价 + 饿了么评价 + 外卖评价分类（三件套） |
| 营销活动复杂分析 | 券明细 (48 节点，重节点轻 SQL) |
| 财务对账监控 | 财务表异常门店 (17 节点，2 输出) |
| POS 编号一致性 | 多 POS 系统门店编号追踪 (21 节点) |
| Cohort 日期×门店网格 | 日期&门店组合表 (11 节点) |
| 简单字段标签计算 | 商品风味分类 (8 节点，CALCULATOR 链) |

## 体量 vs SQL_SCRIPT 占比分布

| 节点数 | ETL 数 | SQL_SCRIPT 占比中位数 | 流派倾向 |
|---|---:|---|---|
| ≤ 5 | 4 | 50%（1~2 个 SQL） | 轻节点重 SQL |
| 6~10 | 8 | 12.5% | 混合 |
| 11~20 | 14 | 5% | 重节点轻 SQL |
| 21~30 | 8 | 4% | 重节点轻 SQL |
| 31~50 | 5 | 2% | 重节点轻 SQL |

**规律**：**ETL 越大，SQL_SCRIPT 占比越低**。原因：大 ETL 通常是业务建模，业务方需要"看图说话"，所以倾向节点化；小 ETL 通常是公式封装，工程师直接写 SQL 最快。

## 从 V1 升 V2 的注意点

V1 ETL 的 JSON schema 经验：
- 主节点定义在 `.meta[]` 数组，每个节点 `{id, type, name, sources, sql?, schema?}`
- `inputs[]` 是顶层声明的所有 input 数据集（dsId + 字段 schema 缓存）
- `cron` 为空表示未配置定时；本批 39 个全部未设 cron，靠手动 / 上游触发
- `description` 几乎全空（只有 DWD 宽表写了"昨日测试 v3"备注），生产 ETL **缺乏文档传统**

V2 升级时建议：
1. 给每个 ETL **补 `description`**（用途 + 上下游 + 调度策略）
2. 给所有 OUTPUT_DATASET **加 `--task` 缓存隔离**（majia-guanyuan Part A），避免多人开发互相覆盖
3. 大节点 ETL（券明细 48）考虑**拆 2~3 个子 ETL**，可读性会断崖式提升
4. 跨多源月度 ODS 的 ETL（顾客标识 43）应该升级到**增量更新模式**（按 ODS 月份分批刷新，而不是全量重跑）

## 引用方式

如果要 review 某个 ETL 的完整 SQL / 节点定义，去**本地 V1 ETL JSON 目录**（路径因人而异，常见放在云盘同步目录或 Git 仓库下），用 jq 抽取：

```bash
# 设置目录变量（按你方实际位置调整）
ETL_DIR="/path/to/your/v1-etl-json"

# 看节点拓扑
jq -r '.meta[] | "[\(.type)] \(.name) ← \(.sources // [] | join(\",\"))"' \
  "$ETL_DIR/<ETL名>.json"

# 看所有 SQL_SCRIPT 节点的 SQL
jq -r '.meta[] | select(.type=="SQL_SCRIPT") | "=== \(.name) ===\n\(.sql)\n"' \
  "$ETL_DIR/<ETL名>.json"

# 看输入数据集列表
jq -r '.inputs[].name' "$ETL_DIR/<ETL名>.json"
```

**注意**：本清单 ETL 名已脱敏（去掉个人后缀），本地实际文件名可能带后缀。建议本地维护一份 `<别名> ↔ <实际文件名>` 映射，不上传到公开仓库。
