# dwd_recsys_alg_exposure_base_20250108 表逻辑说明

## 一、表定位

**曝光-分享-回流** 链路分析表，在曝光粒度上统计分享和回流指标。

---

## 二、整体流程（4 步）

```
数据源 → 分享关联曝光 → 分享关联回流 → 汇总输出
```

---

## 三、每步详解

### Step 1: 数据准备

| CTE | 数据源 | 说明 |
|-----|--------|------|
| `t_return` | `user_share_log_flow` (topic=click) | 回流点击数据 |
| `t_share_from_sharelog` | `user_share_log_flow` (topic=share) | 分享行为数据 |
| `t_exposure` | `dwd_recsys_alg_exposure_base_view_20250402` | 曝光数据 |

**贡献字段**：
- 曝光维度：apptype, uid, mid, vid, sessionid, subsessionid
- 场景信息：pagesource, recommendlogvo, abcode, recommendpagetype, recomtraceid, headvideoid, rootsourceid, hotsencetype
- 流量池：flowpool, level
- 设备信息：clientip, machineinfo_brand/model/system/wechatversion/sdkversion
- 地理信息：province, city
- 时间：ts

---

### Step 2: 分享 → 曝光关联

**目的**：找到每次分享对应的曝光记录

**关联方向**：分享 → 曝光（多对一）

**关联 Key（6 级 Fallback）**：

| 级别 | 关联条件 | 说明 |
|------|---------|------|
| 1 | apptype + mid + vid + **subsessionid** + pagesource + ts>= | 最严格 |
| 2 | apptype + mid + vid + **sessionid** + pagesource + ts>= | 放宽会话 |
| 3 | apptype + mid + vid + **subsessionid** + pagesource | 去掉时间 |
| 4 | apptype + mid + vid + **sessionid** + pagesource | 去掉时间 |
| 5 | apptype + mid + vid + **subsessionid** | 去掉 pagesource |
| 6 | apptype + mid + vid + **sessionid** | 最宽松 |

**必须 Key**：`apptype + mid + vid`

**贡献字段**：
- `is_share` = 该曝光是否产生分享
- `share_cnt` = 该曝光产生的分享次数

---

### Step 3: 分享 ← 回流关联

**目的**：统计每次分享带来的回流

**关联方向**：回流 → 分享（多对一）

**关联 Key**：

| 回流类型 | 关联条件 | 说明 |
|---------|---------|------|
| 一级回流 | `shareid` + vid + apptype | 直接分享带来的回流 |
| N级回流 | `rootshareid` + vid + apptype | 裂变链路所有回流 |

**贡献字段**：

| 字段 | 说明 |
|------|------|
| `is_return_1` | 是否有一级回流 |
| `return_1_pv` | 一级回流 PV |
| `return_1_uv` | 一级回流 UV |
| `return_1_mids` | 一级回流用户列表 |
| `is_return_n` | 是否有 N 级回流 |
| `return_n_pv` | N 级回流 PV |
| `return_n_uv` | N 级回流 UV |
| `return_n_mids` | N 级回流用户列表 |
| `is_return_noself` | 是否有非自己的一级回流 |
| `return_1_uv_noself` | 排除自己的一级回流 UV |
| `return_1_mids_noself` | 排除自己的一级回流用户列表 |
| `is_return_n_noself` | 是否有非自己的 N 级回流 |
| `return_n_uv_noself` | 排除自己的 N 级回流 UV |
| `return_n_mids_noself` | 排除自己的 N 级回流用户列表 |
| `new_exposure_cnt` | 回流带来的新曝光数 |

**注**：`return_n` 包含 `return_1`（rootshareid = shareid 时）

---

### Step 4: 汇总输出

**关联 Key**：`exposure_id`

```sql
t_exposure
LEFT JOIN t_share_with_label_group
ON exposure_id
```

**派生字段**：

| 字段 | 计算逻辑 |
|------|---------|
| `pagesource_new` | pagesource 分类映射（回流后沉浸页、详情页、首页feed等） |
| `extend` | JSON 扩展字段（animationSceneType, extParams, group_name 等） |

---

## 四、关联关系总图

```
┌─────────────────────────────────────────────────────────────────────────┐
│                                                                         │
│   t_exposure                t_share                    t_return         │
│   (曝光)                    (分享)                     (回流)           │
│       │                        │                          │             │
│       │                        │                          │             │
│       │◄───────────────────────┤                          │             │
│       │  Step2: 分享→曝光       │◄─────────────────────────┤             │
│       │  key: apptype+mid+vid  │  Step3: 回流→分享         │             │
│       │       +subsession/     │  key: shareid+vid+apptype│             │
│       │        session         │       rootshareid+vid    │             │
│       │       +pagesource+ts   │       +apptype           │             │
│       │                        │                          │             │
│       ▼                        ▼                          ▼             │
│  ┌─────────────────────────────────────────────────────────────────┐    │
│  │                    最终输出字段                                  │    │
│  ├─────────────────────────────────────────────────────────────────┤    │
│  │  曝光字段: apptype,uid,mid,vid,sessionid,pagesource...          │    │
│  │  分享字段: is_share, share_cnt                                  │    │
│  │  回流字段: is_return_1, return_1_pv/uv/mids                     │    │
│  │           is_return_n, return_n_pv/uv/mids                      │    │
│  │           *_noself (排除分享者自己)                              │    │
│  │           new_exposure_cnt                                      │    │
│  │  派生字段: pagesource_new, extend                               │    │
│  └─────────────────────────────────────────────────────────────────┘    │
│                                                                         │
└─────────────────────────────────────────────────────────────────────────┘
```

---

## 五、核心 Key 汇总

| 步骤 | 关联 Key | 必须 Key |
|------|---------|---------|
| 分享→曝光 | apptype + mid + vid + subsessionid/sessionid + pagesource + ts | apptype + mid + vid |
| 回流→分享(1级) | shareid + vid + apptype | shareid + vid + apptype |
| 回流→分享(N级) | rootshareid + vid + apptype | rootshareid + vid + apptype |
| 汇总→曝光 | exposure_id | exposure_id |

---

## 六、附：曝光→回流关联（new_exposure_cnt 计算）

**目的**：统计每次回流带来多少新曝光

**关联方向**：曝光 → 回流（多对一）

**关联 Key（4 级 Fallback）**：

| 级别 | 关联条件 |
|------|---------|
| 1 | mid + headvideoid + subsessionid |
| 2 | mid + headvideoid + sessionid |
| 3 | mid + subsessionid |
| 4 | mid + sessionid |

**必须 Key**：`mid`

**贡献字段**：`new_exposure_cnt`（回流后用户浏览了多少新内容）

---

## 七、重要洞见

### 1. new_exposure_cnt 包含整条裂变链路

`new_exposure_cnt` **包括所有裂变用户的新曝光**，不只是直接回流用户。

```
A 分享视频 V（shareid_A = rootshareid）
    │
    ├─ B 回流，浏览了 5 个视频 → new_exposure_cnt = 5
    │      │
    │      └─ B 再分享视频 V
    │              │
    │              └─ C 回流，浏览了 3 个视频 → new_exposure_cnt = 3
    │
    └─ 最终汇总：SUM(new_exposure_cnt) = 5 + 3 = 8
```

**原因**：在 `t_share_with_label` 中按 `rootshareid` 分组后 `SUM(new_exposure_cnt)`。

---

### 2. return_n 只统计同一视频的裂变

`return_n_uv` **不包括**用户往下滑分享其他视频带回的人。

```sql
-- 关联条件
ON  a.shareid = c.rootshareid
AND a.vid = c.vid              -- vid 必须匹配
```

**场景说明**：

| 场景 | 是否计入 return_n |
|------|------------------|
| 直接点击分享链接回流看视频 V | ✓ |
| 裂变用户继续分享**同一视频 V** 带回的人 | ✓ |
| 裂变用户往下滑分享**其他视频 W** 带回的人 | ✗ |

```
A 分享视频 V
    │
    ├─ B 点击回流看视频 V ─────────────────► return_n ✓
    │      │
    │      ├─ B 往下滑分享视频 W
    │      │      └─ D 点击回流 ──────────► return_n ✗（vid 不同）
    │      │
    │      └─ B 再分享视频 V
    │              └─ C 点击回流 ──────────► return_n ✓
    │
    └─ A 的 return_n_uv = B + C（只统计视频 V 的裂变）
```

**结论**：`return_n` 只追踪**同一视频**的裂变链路，不跨视频统计。

---

## 八、字段说明

### 曝光维度字段

| 字段 | 类型 | 说明 |
|------|------|------|
| `apptype` | STRING | 应用类型 |
| `uid` | STRING | 用户 ID |
| `mid` | STRING | 设备 ID |
| `vid` | STRING | 视频 ID |
| `sessionid` | STRING | 会话 ID |
| `subsessionid` | STRING | 子会话 ID（更细粒度的会话划分） |
| `pagesource` | STRING | 页面来源 |
| `page` | STRING | 页面标识 |

### 推荐算法字段

| 字段 | 类型 | 说明 |
|------|------|------|
| `recommendlogvo` | STRING | 推荐算法的返回结果日志 |
| `abcode` | STRING | 推荐算法的 AB 分组（如 ab0） |
| `recommendpagetype` | STRING | 区分 pagesource 相同时的场景（三种回流头部、沉浸页下滑、feed下滑） |
| `recomtraceid` | STRING | 推荐服务追踪 ID（后端调取推荐服务前生成，前端降级或后端异常时可能为空） |
| `headvideoid` | STRING | 头部视频 ID（用于回流场景关联） |
| `rootsourceid` | STRING | 区分流量来源（如投流等） |
| `hotsencetype` | STRING | 热点场景类型 |
| `flowpool` | STRING | 流量池标识（非流量池为空字符串，无 null） |
| `level` | STRING | 流量池层级（非流量池为 null） |

### 设备信息字段

| 字段 | 类型 | 说明 |
|------|------|------|
| `clientip` | STRING | 客户端 IP |
| `machineinfo_brand` | STRING | 设备品牌 |
| `machineinfo_model` | STRING | 设备型号 |
| `machineinfo_system` | STRING | 操作系统 |
| `machineinfo_wechatversion` | STRING | 微信版本 |
| `machineinfo_sdkversion` | STRING | SDK 版本 |
| `province` | STRING | 省份 |
| `city` | STRING | 城市 |

### 时间字段

| 字段 | 类型 | 说明 |
|------|------|------|
| `ts` | STRING | 曝光时间戳 |
| `dt` | STRING | 分区字段：日期（格式：20240105） |
| `hh` | STRING | 分区字段：小时（格式：04） |

### 分享指标字段

| 字段 | 类型 | 说明 |
|------|------|------|
| `is_share` | STRING | 该曝光是否产生分享（1/0） |
| `share_cnt` | STRING | 该曝光产生的分享次数 |

### 一级回流字段（直接回流）

| 字段 | 类型 | 说明 |
|------|------|------|
| `is_return_1` | STRING | 该曝光的分享是否带来一级回流（1/0） |
| `return_1_pv` | STRING | 一级回流 PV（点击次数） |
| `return_1_uv` | STRING | 一级回流 UV（回流人数） |
| `return_1_mids` | STRING | 一级回流用户的 mid 列表 |
| `is_return_noself` | STRING | 是否有非自己的一级回流（1/0） |
| `return_1_uv_noself` | STRING | 排除分享者自己的一级回流 UV |
| `return_1_mids_noself` | STRING | 排除分享者自己的一级回流 mid 列表 |

### N级回流字段（裂变回流）

| 字段 | 类型 | 说明 |
|------|------|------|
| `is_return_n` | STRING | 该曝光的分享是否带来 N 级回流（1/0） |
| `return_n_pv` | STRING | N 级回流 PV（整条裂变链的点击次数） |
| `return_n_uv` | STRING | N 级回流 UV（整条裂变链的回流人数） |
| `return_n_mids` | STRING | N 级回流用户的 mid 列表 |
| `is_return_n_noself` | STRING | 是否有非自己的 N 级回流（1/0） |
| `return_n_uv_noself` | STRING | 排除分享者自己的 N 级回流 UV |
| `return_n_mids_noself` | STRING | 排除分享者自己的 N 级回流 mid 列表 |

### 新曝光指标

| 字段 | 类型 | 说明 |
|------|------|------|
| `new_exposure_cnt` | STRING | 回流带来的新曝光数（整条裂变链所有用户浏览的内容总数） |

### 扩展字段

| 字段 | 类型 | 说明 |
|------|------|------|
| `extend` | STRING | JSON 扩展字段（包含 animationSceneType, extParams, group_name 等） |

---

## 九、关键字段关系

```
return_1 ⊂ return_n
├── return_1：只统计直接点击分享链接的回流（by shareid）
└── return_n：统计整条裂变链的回流（by rootshareid），包含 return_1

*_noself 系列：从对应指标中排除分享者自己的回流
├── return_1_uv_noself = return_1_uv - (分享者自己点击)
└── return_n_uv_noself = return_n_uv - (分享者自己在裂变链中的点击)
```
