首页/数据/数仓建模速查/日期相对标记列:谨慎使用
维度与事实设计149 条

日期相对标记列:谨慎使用

在日历维维护相对标记(近 7 日、当月等)可简化报表条件;但固定列是静态快照,需按统计截止日重算,否则会过期。

数仓建模速查数据更新于 2026-10-13

相对标记列是什么

相对标记列是在日历维上追加的布尔列,如一标记「近 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)以防误用。
日历维里本身不随时间变化的部分(是否节假日、周几、财年周序号)适合长期固化;与「今天」相关的部分属于动态语义,二者不要混在同一张快照的同一批列里。

易错点

  • 静态标记被当作永久有效,日报里近 7 日实际是打标那天往前推的 7 天
  • 多张报表共用同一列但统计截止日各不相同,同一指标出现多个数值
  • 把「今天」相关的标记直接写进共享日历维并覆盖更新,历史快照被改掉
  • 标记列没有在字典里写明生成截止日,使用者无法判断是否过期

数据来源与参考

  • 数仓建模实践:日期维度扩展
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌