指标视图的高级技术可实现复杂的计算,例如移动平均值、周期内更改、运行总计和复杂的派生 KPI,同时保持语义层的一致性和可重用性。 本页介绍如何使用窗口度量值进行时序分析和组合,以便从更简单的度量值生成复杂指标。
本页假定熟悉基本指标视图建模概念。 请参阅 模型指标视图。
注释
本页上的示例使用 TPC-H 示例数据集,该数据集为批发供应链建模。 有关 TPC-H 数据集的详细信息,请参阅 tpch。 有关将此数据集用于指标视图的端到端教程,请参阅 教程:使用联接生成完整的指标视图。
窗口测量
重要
此功能为试验性的。
利用窗口度量值,可以在指标视图中使用窗口化、累积或半累加聚合来定义度量值,支持计算,例如移动平均值、周期内更改和运行总计。 本部分包括实际示例。
定义窗口度量值
窗口度量值允许使用开窗聚合、累积聚合或半累加聚合定义度量值。 窗口度量值包括以下必需值:
order:确定窗口排序的维度。
range:定义窗口的跨度,例如滞后、累积或全部数据。 可能的范围值包括:
-
current:包含窗口排序值与当前行的值相等的行。 -
cumulative:包括窗口排序值小于或等于当前行值的所有行。 -
trailing <value> <unit>:包括当前行中按指定时间单位数向后移动的行,例如trailing 3 months。 这不包括当前单元。 例如,trailing 3 months排除当前月份。 -
leading <value> <unit>:从当前行开始的行,包括往前的行数,按指定的时间单位数,例如leading 7 days。 这不包括当前单元。 -
all:包括所有行,而不考虑窗口值。
-
semiadditive:指定在查询
GROUP BY中不包含订单字段时如何聚合度量值。 可取值包括first和last。
滞后、移动或前导窗口测量示例
以下示例计算下订单的唯一客户的滚动 7 天计数。 此指标通过显示截至每个日期的一周中购买的不同客户数,帮助跟踪客户参与趋势。
version: 1.1
source: samples.tpch.orders
filter: o_orderdate > DATE'1998-01-01'
dimensions:
- name: date
expr: o_orderdate
measures:
- name: t7d_customers
expr: COUNT(DISTINCT o_custkey)
window:
- order: date
range: trailing 7 day
semiadditive: last
对于此示例,以下配置适用:
-
order:
date指定日期维度对窗口进行排序。 -
range:规范
trailing 7 day将窗口定义为每个日期之前的 7 天,不包括日期本身。 -
semiadditive:
last指示当日期不是分组列时,将使用 7 天窗口中的最后一个值。
环比窗口期度量示例
以下示例通过将今天的收入(所有订单价格的总和)与昨天的收入进行比较来计算日间销售额增长。 此指标有助于识别每日销售趋势,并显示收入百分比变化,这对于监视业务绩效和发现异常非常有用。
version: 1.1
source: samples.tpch.orders
filter: o_orderdate > DATE'1998-01-01'
dimensions:
- name: date
expr: o_orderdate
measures:
- name: previous_day_sales
expr: SUM(o_totalprice)
window:
- order: date
range: trailing 1 day
semiadditive: last
- name: current_day_sales
expr: SUM(o_totalprice)
window:
- order: date
range: current
semiadditive: last
- name: day_over_day_growth
expr: (MEASURE(current_day_sales) - MEASURE(previous_day_sales)) / MEASURE(previous_day_sales) * 100
对于此示例,适用以下条件:
使用了两个窗口度量值:一个用于计算前一天的总销售额,另一个用于计算当天的总销售额。
第三个度量值计算当前和前几天之间的百分比变化(增长)。
累计(持续更新的)总值示例
以下示例从数据集的开头计算到每个日期的累计销售收入。 此运行总数显示随时间推移产生的总收入量,有助于跟踪年度收入目标的进度或分析长期增长模式。
version: 1.1
source: samples.tpch.orders
filter: o_orderdate > DATE'1998-01-01'
dimensions:
- name: date
expr: o_orderdate
- name: customer
expr: o_custkey
measures:
- name: running_total_sales
expr: SUM(o_totalprice)
window:
- order: date
range: cumulative
semiadditive: last
以下详细信息突出显示此定义的关键部分:
order:指定定义窗口中记录排序的维度。 在此示例中,
date按时间顺序对窗口进行排序。range:
cumulative将窗口设置为从数据集开始到并包括每个日期的所有数据。半加性:当查询中未包含
last时,date控制度量的聚合方式。 如果查询GROUP BY中不包含日期维度,度量值将返回最后一个(最近)累积值,而不是在所有日期之间求和。
日期期间度量值示例
以下示例计算年初至今的销售收入。 该指标显示每年从 1 月 1 日起至当前日期的累计收入,并在每个新年开始时重置。 此指标对于比较当前年份的性能和跟踪年度目标的进度至关重要。
version: 1.1
source: samples.tpch.orders
filter: o_orderdate > DATE'1997-01-01'
dimensions:
- name: date
expr: o_orderdate
- name: year
expr: DATE_TRUNC('year', o_orderdate)
measures:
- name: ytd_sales
expr: SUM(o_totalprice)
window:
- order: date
range: cumulative
semiadditive: last
- order: year
range: current
semiadditive: last
以下详细信息突出显示此定义的关键部分:
使用两个窗口测量:一个用于在
date维度上进行累积求和,另一个用于将求和限制在current年份内。维度
year限制累积总和,使其仅在当前年份内计算。
半累加性度量示例
以下示例计算不应在日期之间求和的帐户余额(不能将星期一的余额添加到星期二的余额以获取总余额)。 相反,当聚合多天时,指标将返回最近的余额。 但是,该度量值仍可跨客户求和,以在给定的一天显示所有帐户的总余额。
version: 1.1
dimensions:
- name: date
expr: date
- name: customer
expr: customer_id
measures:
- name: semiadditive_balance
expr: SUM(balance)
window:
- order: date
range: current
semiadditive: last
以下详细信息突出显示此定义的关键部分:
order:指定定义窗口中记录排序的维度。 在此示例中,
date按时间顺序对窗口进行排序。范围:
current将窗口限制为一天,且不跨天聚合。semiadditive:
last在多天内聚合时返回最近的余额。
查询窗口度量值
可以使用窗口度量值查询指标视图,就像任何其他指标视图一样。 以下示例查询指标视图中的数据:
SELECT
state,
DATE_TRUNC('month', date),
MEASURE(t7d_customers) as m
FROM my_metric_view
WHERE date >= DATE'2024-06-01'
GROUP BY ALL
可组合性
指标视图是可组合的。 可以构建新的维度和度量值,这些新维度和度量值以参考现有的为基础,而无需从头开始重写逻辑。 这样可以减少重复,并使复杂的指标定义更易于维护。
可组合性在两个层面上发挥作用:一个是在单一指标视图内,另一个是跨越多个指标视图。 指标视图可以使用另一个指标视图作为其源,从而可以分层定义并逐步生成更丰富的语义模型,而无需复制逻辑。
可组合性支持以下引用模式:
- 新维度中的早期维度。
- 新度量值中的维度和早期度量值。
- 新维度中用作源的指标视图中的维度。
- 新度量值中用作源的指标视图中的维度和度量值。
定义可组合性的度量值
在本 measures 部分中,可以从源指标视图引用度量值或之前在同一指标视图中定义的度量值。 此方法可提高语义层的一致性、可审核性和维护。
| 度量类型 | 说明 | 示例 |
|---|---|---|
| 原子 | 对源列进行简单直接聚合。 这些构成基础模块。 | SUM(o_totalprice) |
| 组成 | 使用 MEASURE() 函数以数学形式组合一个或多个其他衡量指标的表达式。 |
MEASURE(total_revenue) / MEASURE(order_count) |
示例:平均订单值(AOV)
以下示例使用两个原子度量 total_revenue 值(订单价格和)和 order_count (订单数)定义平均订单值(AOV)。 该 avg_order_value 度量值引用两个原子度量值。
version: 1.1
source: samples.tpch.orders
measures:
# Total Revenue
- name: total_revenue
expr: SUM(o_totalprice)
# Order Count
- name: order_count
expr: COUNT(1)
# Composed Measure: Average Order Value (AOV)
- name: avg_order_value
# Defines AOV as Total Revenue divided by Order Count
expr: MEASURE(total_revenue) / MEASURE(order_count)
total_revenue如果定义更改(例如,要排除税),avg_order_value则会自动使用更新后的定义。
使用条件逻辑的可组合性
可以使用可组合性来创建复杂比率、条件百分比和增长率,而无需依赖窗口函数进行简单的周期内计算。
示例:履行率
以下示例计算履行率:状态 'F' 为(已履行)的订单百分比。 该度量将已完成的订单除以总订单。
version: 1.1
source: samples.tpch.orders
measures:
# Total Orders (denominator)
- name: total_orders
expr: COUNT(1)
# Fulfilled Orders (numerator)
- name: fulfilled_orders
expr: COUNT(1) FILTER (WHERE o_orderstatus = 'F')
# Composed Measure: Fulfillment Rate (Ratio)
- name: fulfillment_rate
expr: MEASURE(fulfilled_orders) / MEASURE(total_orders)
format:
type: percentage
可组合性的最佳做法
-
首先定义原子度量值:在定义引用它们的度量值之前,先建立基本度量值(
SUM、COUNT、AVG)。 -
为引用使用
MEASURE():在MEASURE()中引用另一个度量值时使用expr函数。 请勿手动重复聚合逻辑。 例如,如果两个值的度量值已存在,请避免SUM(a) / COUNT(b)。 -
确定可读性优先级:使用明确的数学公式撰写度量值。 例如,
MEASURE(gross_profit) / MEASURE(total_revenue)比单个复杂 SQL 表达式更清晰。 - 添加语义元数据:使用语义元数据设置下游工具的组合度量值(例如百分比或货币)的格式。 在 指标视图中查看代理元数据。