一、最外层:最终聚合
SELECT
t1.event_day, t1.cmatch, t1.trans_type, t1.exp_id,
sum(eshow), -- 曝光
sum(click), -- 点击
sum(charge), -- 实际消费
sum(convert_num), -- 转化数
sum(target_charge) -- 目标消费(即"该花多少钱")
FROM t1 LEFT JOIN t2
ON (searchid_decimal = search_id AND ideaid = idea_id)
GROUP BY event_day, cmatch, trans_type, exp_id核心思路: t1 提供每次曝光的展/点/消,t2 补充对应的转化数和目标消费,按searchid + ideaid一对一关联。
一条请求就是一个
searchid(检索 id),一个请求可能带下来很多广告;一个ideaid(创意 id)就是一个广告。所以searchid + ideaid才能唯一确定一个请求里的唯一广告。
二、t1 展点消主体(每条曝光记录)
SELECT
event_day, searchid_decimal, ideaid, cmatch,
-- 实验分组
CASE WHEN ovl_exp LIKE '%153613-0%' THEN 'exp'
WHEN ovl_exp LIKE '%153613-dz%' THEN 'dz' END AS exp_id,
trans_type,
eshow, -- 曝光(表里自带字段)
clk AS click, -- 点击
-- 消费计算:区分计价方式
CASE
WHEN (bid_type='3' AND pricing_type='1') OR bid_type='2'
THEN price / 1000 / 100 -- oCPM: price 单位是厘/千次
ELSE clk * price / 100 -- CPC: 点击 × 单价
END AS charge
FROM fc_nad.nativeads_feed_asp_view
WHERE event_day BETWEEN '20251114' AND '20251119'
AND event_type = 'browser'
AND cmatch = '719'
AND (ovl_exp LIKE '%153613-0%' OR ovl_exp LIKE '%153613-dz%')要点:
- 一行 = 一次曝光事件
eshow、clk是表自带的字段charge需要根据出价类型自己算
三、t2 转化汇总(四路 UNION ALL)
t2 的作用是:把所有转化来源合到一起,最终按search_id, idea_id聚合出convert_num和target_charge。
第 1 路:常规 oCPX 转化
来源: nativeads_ocpx_charge_hour
产出: convert_num(转化数)+ target_charge(目标消费)- 处理了深度转化逻辑:如果
is_ocpc_deep=1且deep_trans_type不是 28/29,就用深度出价和深度转化数 target_charge=ocpc_bid × convert_num / 100- 但对
trans_type in (14,80-88,90,118)这些特殊类型,target_charge = 0(因为第 3、4 路单独算)
第 2 路:视频播放转化(补充)
来源: nativeads_video_play_conv (ocpx_join_flag = '0')
产出: 同上,convert_num + target_chargeocpx_join_flag = '0'表示没被第 1 路 join 上的漏网转化- 逻辑和第 1 路基本一致,是补数据用的
第 3 路:特殊 trans_type 的 ROI 目标消费
来源: asp_view LEFT JOIN nativeads_ods_ocpc_all_convert
适用: trans_type in (14,78,80-88,90)
产出: convert_num = 0, target_charge = 按ROI逻辑算关键:convert_num** 硬编码为 0**,因为转化数已经在第 1、2 路算了,这里只补 target_charge。
target_charge 逻辑:
- 非 ROI 出价:
ocpc_bid × convert_num / 100 - ROI 出价:
convert_value / bw_idf_ratio(转化价值 / ROI 系数)
第 4 路:trans_type = 118(明投 ROI)
来源: asp_view LEFT JOIN nativeads_feed_ocpc_all_convert
适用: trans_type = 118
产出: convert_num = 0, target_charge = 按明投ROI逻辑算和第 3 路类似,但:
- 用的转化表不同(
nativeads_feed_ocpc_all_convert) - ROI 判断逻辑不同(明投2阶段 / 明投1阶段 / 暗投)
- 明投2阶段:
convert_value / movie_troi
四路关系总结
| 路径 | 贡献 convert_num | 贡献 target_charge | 覆盖的 trans_type |
|---|---|---|---|
| 第1路 | ✅ | ✅(常规类型) | 常规(排除14,80-88,90,118) |
| 第2路 | ✅ | ✅(常规类型) | 同上,补漏 |
| 第3路 | ❌ (=0) | ✅(ROI类型) | 14,78,80-88,90 |
| 第4路 | ❌ (=0) | ✅(明投ROI) | 118 |
设计意图: 转化数只算一次(1、2路),目标消费按不同 trans_type 的计价逻辑分路计算,避免重复。对,t1 是展点消,t2 是转化。t2 最终只产出两个值:convert_num(转化数)和 target_charge(目标消费),按 search_id + idea_id 聚合。
下面逐路拆解:
第 1 路:nativeads_ocpx_charge_hour(常规转化)
这是最核心的转化数据源,有两层嵌套:
内层 — 从原始表取数据,做两个 IF 判断:
-- 出价:是深度转化就用深度出价,否则用普通出价
ocpc_bid_2 = IF(is_ocpc_deep=1 AND deep_trans_type NOT IN ('28','29'),
deep_ocpc_bid, ocpc_bid)
-- 转化数:是深度转化就看深度转化类型是否匹配,否则直接用 convert_num
convert_num = IF(is_ocpc_deep=1 AND deep_trans_type NOT IN ('28','29'),
IF(convert_num>0 AND array_contains(..., deep_trans_type), convert_num, 0),
convert_num)简单说:如果广告主开了深度转化,就用深度的出价和转化数;否则用普通的。
外层 — 算 target_charge:
target_charge = CASE
WHEN trans_type IN (14,80-88,90,118) THEN 0 -- 这些类型留给第3、4路算
ELSE ocpc_bid_2 * convert_num / 100.0 -- 常规:出价 × 转化数
END第 2 路:nativeads_video_play_conv(视频转化补漏)
逻辑和第 1 路几乎一样,区别:
- 数据源不同(视频播放转化表)
- 多了
ocpx_join_flag = '0'过滤 — 意思是”没被第 1 路的 ocpx 表 join 上的记录” - 先做了一次
GROUP BY search_id, idea_id, event_day去重(用 MAX 取各字段) convert_type_list的分隔符是#而不是第 1 路的\002
本质:第 1 路漏掉的转化,从这个表补上。
第 3 路:ROI 出价的目标消费(trans_type = 14,78,80-88,90)
结构是 asp_view(t21)LEFT JOIN 转化表(t22):
t21(左表)— 从 asp_view 取曝光记录,并判断是否 ROI 出价:
roi_tag = CASE
WHEN pla_rank=1 AND bw_idf_ratio>0 THEN 'ROI出价'
ELSE '非ROI出价'
ENDt22(右表)— 从 nativeads_ods_ocpc_all_convert 取转化价值:
-- convert_num: trans_type 和 convert_type 匹配就算 1 次转化
-- convert_value: 从 convert_value_time 数组里炸开,取金额部分合并后算 target_charge:
target_charge = CASE
WHEN 非ROI出价 THEN ocpc_bid * convert_num / 100 -- 普通算法
WHEN ROI出价 THEN convert_value / bw_idf_ratio -- 转化价值 / ROI系数
ENDconvert_num** 写死 = 0**,因为转化次数已经在第 1、2 路算过了,这里只补目标消费。
第 4 路:明投 ROI 的目标消费(trans_type = 118)
和第 3 路结构完全一样,区别:
| 第 3 路 | 第 4 路 | |
|---|---|---|
| trans_type | 14,78,80-88,90 | 118 |
| 转化表 | nativeads_ods_ocpc_all_convert | nativeads_feed_ocpc_all_convert |
| ROI 判断 | pla_rank + bw_idf_ratio | is_movie_roi_second_stage 等字段 |
| ROI 算法 | convert_value / bw_idf_ratio | convert_value / movie_troi |
四路汇总
最后所有路 UNION ALL 到一起,外面套一层:
SELECT search_id, idea_id,
SUM(convert_num) AS convert_num, -- 只有 1、2 路贡献
SUM(target_charge) AS target_charge -- 四路都贡献
FROM (第1路 UNION ALL 第2路 UNION ALL 第3路 UNION ALL 第4路)
GROUP BY search_id, idea_id然后通过 LEFT JOIN 关联回 t1,就把转化数据挂到每条展点消记录上了。
这样清楚了吗?
更新: 2026-03-22 21:00:57
原文: https://www.yuque.com/dongpozhouzi-mshe3/zhm85g/lkqvuy8v1ofzq89w