在指标视图中使用详细信息级别(LOD)表达式

详细信息级别(LOD)表达式允许你指定计算聚合的粒度,这与查询中的字段(也称为维度)无关。 这样,您就可以计算诸如总占比之类的指标,其中分母的聚合粒度比查询粒度更粗。

什么是详细表达式级别?

明细级别表达式让您能够精确指定在计算聚合结果时使用哪些字段,而不受查询中现有字段的影响。 这样就可以对计算范围进行精细控制。

细节层级表达式有三种类型:

  • 固定详细级别:按表达式本身中指定的预定义字段集进行聚合,忽略查询中的其他字段。
  • 较粗的详细程度:通过在分组时排除特定字段,按比查询更粗的粒度进行聚合。
  • 更细的明细级别:通过添加额外字段,按比查询更细的粒度进行聚合,然后再将结果重新聚合到查询的粒度。

固定的详细信息级别

固定级别的详细信息表达式以定义的粒度计算聚合,忽略查询中的字段。 在指标视图中,固定 LOD 表达式直接定义在列定义的 expr 字段中,并使用带有 PARTITION BY 子句的 SQL 窗口函数。

何时使用固定级别的详细信息

需要满足以下条件时,请使用固定级别的详细信息表达式:

  • 不依赖于查询分组:具有跨所有用途的静态分区的指标。
  • 数据集级聚合:与行级别分组相比的全局聚合(例如,按优先级计算总销售额的百分比)。
  • 多级层次:在同一视图中可以查看到详细级别和汇总级别的度量。

语法

固定 LOD 表达式使用 SQL 窗口函数 在定义的粒度上计算聚合。 将窗口函数直接放在字段定义中的 expr 字段中:

fields:
  - name: <lod_name>
    expr: <AGGREGATE_FUNCTION>(<column>) OVER (PARTITION BY <dim1>, <dim2>, ...)

若要聚合整个数据集,请忽略 PARTITION BY 条件,并在 OVER 后留空括号。

示例:按订单优先级统计的总销售额

假设你想要定义一个指标视图,其中每个订单的销售量与其优先级组的总销售额进行比较。 以下示例在源查询中计算 priority_total_price ,并将其公开为标识字段:

version: 1.1

source: samples.tpch.orders

fields:
  - name: order_priority
    expr: o_orderpriority
  - name: order_date
    expr: o_orderdate
  - name: priority_total_price
    expr: SUM(o_totalprice) OVER (PARTITION BY o_orderpriority)

measures:
  - name: total_sales
    expr: SUM(o_totalprice)

  - name: pct_of_priority_total
    expr: SUM(o_totalprice) / ANY_VALUE(priority_total_price)

priority_total_price 字段直接在其 expr 字段中定义每个优先级组的固定总计。 该 pct_of_priority_total 度量将单个订单销售额除以一个固定的总数以生成百分比,无论查询如何对结果进行分组。

注释

在度量值表达式中引用固定级别的详细信息字段时,将其包装在聚合函数中。 当值在组中为常量时使用 ANY_VALUE ,如前面的示例所示。

使用 SQL 创建指标视图

若要在目录资源管理器外创建此指标视图,请用 CREATE OR REPLACE VIEW ... WITH METRICS LANGUAGE YAML AS 包裹 YAML,并将定义放在 $$ 分隔符之间:

CREATE OR REPLACE VIEW catalog.schema.sales_by_priority WITH METRICS LANGUAGE YAML AS
$$
  version: 1.1

  source: samples.tpch.orders

  fields:
    - name: order_priority
      expr: o_orderpriority
    - name: order_date
      expr: o_orderdate
    - name: priority_total_price
      expr: SUM(o_totalprice) OVER (PARTITION BY o_orderpriority)

  measures:
    - name: total_sales
      expr: SUM(o_totalprice)

    - name: pct_of_priority_total
      expr: SUM(o_totalprice) / ANY_VALUE(priority_total_price)
$$

本页中的较粗略细节层级示例遵循相同的模式。

对固定级别的详细信息表达式进行筛选

在应用任何查询时筛选器之前,将计算详细表达式的固定级别。 若要将筛选器应用于固定 LOD 计算,请使用 CASE 语句或 FILTER 子句,在窗口函数表达式中包含筛选条件。

更粗略的详细信息级别

较粗粒度的详细信息级别表达式通过从分区中排除一个或多个字段,以比查询更粗的粒度进行聚合。 在指标视图中,粗略的 LOD 表达式是使用有范围规范的 窗口度量 实现的 all 。

何时使用更粗糙的详细信息级别

如果需要,请使用更粗细的详细信息表达式级别:

  • 动态分组:适应查询分组的聚合(例如,任何选定字段的总计百分比)。
  • 筛选器感知聚合:在考虑查询时的筛选器范围内,以较粗粒度进行计算。

语法

对于要从分区中排除的每个字段,请使用 range: all 定义一个窗口度量:

measures:
  - name: <measure_name>
    expr: <AGGREGATE_EXPRESSION>
    window:
      - order: <field_to_exclude>
        range: all
        semiadditive: last

若要排除多个字段,请将条目添加到每个字段的 window 数组中。

示例:总销售额的百分比

计算每个订单优先级的总销售额百分比:

version: 1.1

source: samples.tpch.orders

fields:
  - name: order_priority
    expr: o_orderpriority

measures:
  - name: total_sales
    expr: SUM(o_totalprice)

  - name: all_priorities_sales
    expr: SUM(o_totalprice)
    window:
      - order: order_priority
        range: all
        semiadditive: last

  - name: pct_of_total_sales
    expr: SUM(o_totalprice) / MEASURE(all_priorities_sales)

在本示例中:

  • total_sales 聚合在查询的分组级别。
  • all_priorities_sales 使用 range: all 来计算所有订单优先级的总数,并忽略查询中的 order_priority 字段。
  • pct_of_total_sales 将优先级级别的销售额除以总计以生成百分比。

更精细的详细信息级别

更细的细节表达式会以比查询更细粒度计算聚合,然后将结果重新聚合回查询的粒度。 内部聚合会在查询字段加上你包含的另一个或多个额外字段进行评估,外部聚合会将这些值重新叠加。 在度量视图中,更细粒度的 LOD 表达式是使用包含 include 列表和 outer_aggregate 函数的 partition 块的度量。

何时使用更精细的详细信息级别

需要时使用更细致的细节表达:

  • 聚合上的聚合:先计算每个实体的聚合值,例如每位客户的总收入,然后在查询粒度上再进行汇总,例如对所有客户求平均值。
  • 粒度无关汇总:以比查询粒度更细的粒度计算内部度量,并随着查询粒度的变化自动汇总。

语法

定义一个带有 partition 块的测度。 该 partition 块向查询的粒度中添加用于内部聚合的字段,并指定用于将结果重新汇总的聚合:

measures:
  - name: <measure_name>
    expr: <INNER_AGGREGATE_EXPRESSION>
    partition:
      include: [<field1>, <field2>, ...]
      outer_aggregate: <AGGREGATE_FUNCTION>

在此语法中:

  • expr 是内部聚合。 它是按查询的粒度以及 include 中的字段进行评估的。
  • include 指定一个或多个字段,在计算内部聚合时将其添加到查询粒度中。 每个条目必须是度量视图中定义的字段。
  • outer_aggregate 是用于将内部结果汇总回查询粒度的聚合函数。

注释

outer_aggregate必须是单参数聚合函数:SUM、AVG、COUNT、MIN、MAX 或 MEDIAN。 COUNT(DISTINCT ...) 而多参数函数(如 ) PERCENTILE 不支持作为外聚合,但你可以在 expr中使用 。 更细粒度的度量也不能使用 window 块,并且不能引用其他更细粒度的度量或窗口度量。

示例:每个客户的平均收入

假设你想计算每位客户的平均收入,并按查询所使用的粒度进行汇总,例如按订单优先级。 计算每个客户的总收入作为内部总量,然后用外部总量对客户平均:

version: 1.1

source: samples.tpch.orders

fields:
  - name: order_priority
    expr: o_orderpriority
  - name: customer
    expr: o_custkey

measures:
  - name: total_revenue
    expr: SUM(o_totalprice)

  - name: avg_revenue_per_customer
    expr: SUM(o_totalprice)
    partition:
      include: [customer]
      outer_aggregate: AVG

在本示例中:

  • total_revenue 聚合在查询的分组级别。
  • avg_revenue_per_customer 在(order_priority、customer)这一粒度上计算 SUM(o_totalprice),得出每个客户在某一优先级内的总收入,然后使用 outer_aggregate: AVG 将这些按客户计算的总收入平均汇总回查询粒度。

像查询其他指标一样查询该指标。 仅在计算内部聚合时,才会将 include 字段添加到查询粒度中:

SELECT order_priority, MEASURE(avg_revenue_per_customer)
FROM catalog.schema.orders_mv
GROUP BY order_priority

每一行返回该订单优先级的每名客户平均收入。

其他资源