订单过程怎么分粒度
交易域的订单通常有两个自然粒度:订单头(一笔订单一行)和订单明细行(一笔订单中的一个商品行一行)。两者分别建事实表,用订单号作为退化维度关联,避免把两种粒度塞进一张表造成金额重复计算。
基本信息
| 头粒度 | 一行 = 一笔订单,承载订单级金额与状态 |
|---|---|
| 行粒度 | 一行 = 一个订单商品行,承载数量、单价、行金额 |
| 关联键 | 订单号作为退化维度直接存在事实表中 |
| 常用维度 | 日期、用户、商品、门店、渠道、促销 |
| 口径注意 | 头级优惠分摊到行需要明确规则 |
典型使用场景
- 订单量统计:按头粒度计算订单笔数,行粒度会得到商品行数
- 销售额统计:按行粒度汇总金额,可下钻到商品与类目
- 客单价分析:订单金额除以订单笔数,两个粒度各自提供一半数据
- 履约时效:头表的各里程碑时间用于计算发货与签收耗时
- 优惠归因:头级优惠需要按规则分摊,才能得到行级真实成交价
头行两表查询
头行两表查询
-- 头表:一笔订单一行,用于订单笔数与订单级金额
-- fact_order(order_id, user_sk, order_date_key, order_amt, status)
-- 行表:一个商品行一行,用于商品级与类目级汇总
-- fact_order_item(order_id, product_sk, qty, item_amt, discount_amt)
SELECT p.cat_l1_name,
sum(i.qty) AS sale_qty, -- 行级数量
sum(i.item_amt) AS sale_amt -- 行级金额,不含头级优惠
FROM fact_order_item i
JOIN dim_product p ON i.product_sk = p.product_sk
WHERE i.dt = '2026-10-12'
GROUP BY p.cat_l1_name;
-- 订单笔数必须从头表取,直接对行表 count 会得到商品行数
-- SELECT count(DISTINCT order_id), count(1) FROM fact_order_item WHERE dt='2026-10-12';头行两表对照
| 对比项 | 订单头事实表 | 订单明细行事实表 |
|---|---|---|
| 粒度 | 一笔订单一行 | 一个商品行一行 |
| 主要度量 | 订单金额、优惠、状态 | 数量、单价、行金额 |
| 典型分析 | 订单量、客单价、履约 | 品类销售、商品排行 |
| 关联方式 | 订单号作为退化维度 | 订单号关联回头表 |
头级与行级度量不能混算:把订单级优惠与行级金额放在同一个 sum 里,会按行数重复计入优惠。优惠要不要分摊、按什么规则分摊,是必须在文档里写明的口径决策。
头表与行表通过订单号关联做明细查询时,如果行表存在重复行(同一商品行被重复投递),订单级金额会被成倍放大。关联前先确认行表已按业务主键去重。