首页/数据/数据工程与 ETL 速查/数仓转换常用 SQL 模式
管道基础52 条

数仓转换常用 SQL 模式

日常加工大多落在几类模式上:按维度聚合、取最新一条、维表补全、窗口排名、区间累计。掌握这些模式,多数层间加工不必引入复杂框架。

常见转换模式

数仓层间加工绝大多数落在几类模式上:按维度聚合、按主键取最新一条、维表补全、分组排名、区间累计与同环比。掌握这些写法,多数需求不需要引入额外的框架或复杂作业,也能让不同人写出的 SQL 保持一致的思路。

最容易出错的两处

一是聚合与窗口函数的执行顺序:窗口函数在 WHERE 之后执行,要过滤窗口结果必须再包一层子查询。二是维表 join 前没有去重,一行明细匹配到多行维度,行数被放大、金额被重复累计,这是汇总对不上的最高频原因。

基本信息

聚合模式GROUP BY 维度做求和、计数、去重计数
取最新一条ROW_NUMBER 按主键分组,排序后取 rn=1
维表补全去重后的维度 LEFT JOIN 明细
排名与 TopN窗口函数按分组排序取前 N
区间累计窗口范围聚合(累计至当日)
同环比LAG 取上一期数值做对比

模式与适用场景

模式适用要点
按维度聚合日汇总、渠道汇总过滤条件写在聚合之前以减少数据量
取最新一条状态类明细去重排序字段要与业务「最新」的定义一致
维表补全补充渠道名、品类名等描述字段关联前先对维表按主键去重
TopN 排名热销商品、活跃用户榜先聚合再排名,避免在明细上直接排名
区间累计与同环比累计指标、同比环比用窗口函数或自关联,注意补齐缺失日期

典型使用场景

  • 每日销售汇总:按日期与渠道聚合,供看板使用
  • 用户最新状态:从变更明细中取每个用户的最新一条
  • 维度补全:给订单明细补上渠道名称与地区信息
  • 榜单类需求:按品类取销售额前 N 的商品
  • 累计指标:当月累计成交额、累计活跃用户数
  • 同环比对比:与上一期、去年同期对比,观察趋势

按维度聚合与取最新一条

按维度聚合与取最新一条
-- 按渠道每日汇总:先过滤分区,再聚合
SELECT dt, channel, SUM(amount) AS amount
FROM dwd_order
WHERE dt BETWEEN '2026-10-01' AND '2026-10-11'
GROUP BY dt, channel;

-- 每个用户最近一笔订单:窗口函数在 WHERE 之后执行,必须再包一层
SELECT * FROM (
  SELECT o.*, ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY ts DESC) AS rn
  FROM dwd_order o WHERE dt = '2026-10-11'
) t WHERE rn = 1;

维表补全与同环比

维表补全与同环比
-- 维表先去重再关联,避免行数放大导致金额重复累计
SELECT o.order_id, c.channel_name
FROM dwd_order o
LEFT JOIN (
  SELECT channel_code, MAX(channel_name) AS channel_name
  FROM dim_channel GROUP BY channel_code
) c ON o.channel_code = c.channel_code;

-- 同环比:用 LAG 取上一期数值,按维度分组、按时间排序
SELECT dt, channel, amount,
       LAG(amount, 1) OVER (PARTITION BY channel ORDER BY dt) AS amount_prev_day
FROM dws_channel_1d;   -- amount_prev_day 为 NULL 表示上一期缺失,不要当成 0
过滤窗口函数结果必须使用子查询或 CTE:把 rn = 1 写在同一层的 WHERE 里,此时窗口还没计算出来,语句会直接报错或被引擎按其它语义处理。
LEFT JOIN 维表缺失时,补 NULL 还是补默认值要在链路上统一约定:两种处理混用会让下游汇总口径漂移,且很难从结果反推原因。

易错点

  • 窗口函数在 WHERE 之后执行,直接过滤 rn 会报错,必须再包一层子查询
  • join 前不对维表去重,行数被放大导致金额重复累计,是汇总对不上的高频原因
  • LEFT JOIN 缺失时补 NULL 与补默认值混用,下游口径漂移且难以追溯
  • 同环比直接对缺失值做减法,把 NULL 当成 0,得出错误的增长率

数据来源与参考

  • Kimball《The Data Warehouse Toolkit》维度建模与聚合模式
  • Apache Hive LanguageManual:窗口函数
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌