相对标记列是什么
相对标记列是在日历维上追加的布尔列,如一标记「近 7 日」「本月」「去年同期」等,作用是让报表直接按 is_last_7d = 1 过滤,省掉一堆日期加减。它的本质问题是动态概念被固化成静态快照:列一旦写入,就绑定在生成它的那个截止日上,隔天再看就过期了。
基本信息
| 常见列 | is_last7d / is_last30d / is_this_month |
|---|---|
| 写入时机 | 日历维加工时按某个截止日一次性打标 |
| 有效期 | 仅对打标所用的截止日成立 |
| 失效表现 | 隔天或跨报表使用时结果偏一天或偏一段 |
| 推荐替代 | 查询侧按当前日期或参数 :asof 动态计算 |
| 适用平台 | Hive / Spark SQL / MySQL 8 的日期维表 |
典型使用场景
- 固定口径快照:监控昨天的日报需要在某一时点固化「近 7 日」定义
- 报表工具兼容:BI 工具不支持复杂日期函数时用标记列代替滚动条件
- 历史复盘:把某次活动的「近 7 日」窗口连同截止日一起存证
- 简化培训:让业务同学用等值条件而非区间条件写自助查询
- 性能取舍:预打标可避免大表上无法下推的日期函数
按截止日重算
按截止日重算
SELECT date_key, cal_date,
CASE WHEN cal_date BETWEEN date_sub(:asof, 6) AND :asof
THEN 1 ELSE 0 END AS is_last_7d, -- 近 7 日含截止日当天
CASE WHEN date_format(cal_date, 'yyyy-MM') = date_format(:asof, 'yyyy-MM')
THEN 1 ELSE 0 END AS is_this_month
FROM dim_date
WHERE cal_date <= :asof; -- 截止日之后的行不给标记,防止把未来数据算进来标记列风险对照
| 写法 | 成立条件 | 风险 |
|---|---|---|
| 静态预打标 | 仅对打标截止日成立 | 隔天口径偏一天 |
| 查询侧动态计算 | 每次执行按当时日期 | 口径随日期变化,需写明基准 |
| 参数化截止日 | 调用方显式传 :asof | 漏传参数会取默认值,易误用 |
跨报表共用同一列但各自截止日不同时极易出错;滚动窗口建议改由查询侧用函数计算,或者把标记列命名为带日期的快照列(如 is_last7d_asof_20261001)以防误用。
日历维里本身不随时间变化的部分(是否节假日、周几、财年周序号)适合长期固化;与「今天」相关的部分属于动态语义,二者不要混在同一张快照的同一批列里。