模型度量視角

指標檢視為你的資料建立語意層,將表格和檢視轉換成標準化的商業指標。 他們定義要衡量什麼、如何彙整,以及如何分割。 因此,組織內的每位使用者都能針對相同的KPI報告相同值,消除報告不一致,並能靈活分析各欄位。

你定義的核心元件包括來源、連接、濾波器、欄位和度量。

如需完整範例,包含連接、欄位、度量與代理元資料,請參見 教學:建立結合與資料建模的度量視圖。

核心元件

度量視角包含以下元素:

組件 Description 範例
來源 包含資料的基底資料表、檢視表或 SQL 查詢。 samples.tpch.orders
加入 建立表格、視圖與度量視圖之間的關係以豐富資料。 將 orders 表格與 customers 表格在 customer_key 上連接
篩選 對來源資料施加條件以定義範圍。
  • status = 'completed'
  • order_date > '2024-01-01'
Fields 欄位用於分組、篩選及彙整指標。 包含類別欄位及未彙總的數字欄位。 也稱為維度。 產品類別、訂單月份、單價
措施 欄位聚合產生指標。 COUNT(o_orderkey) 作為訂單數量,SUM(o_totalprice) 作為總收入

定義來源

您可以使用類似數據表的資產或 SQL 查詢作為計量檢視的來源。 你至少必須對任何參考的資產擁有 SELECT 權限。

類表格資產是指任何暴露表格結構並支援SELECT查詢的 Unity 目錄物件,包括表格、檢視、實體化檢視、串流表格、外部表格、系統表格及度量檢視。

使用類似表格的資產作為來源

若要使用類似資料表的資產作為來源,請指定完全限定的名稱。 例如: samples.tpch.orders 。

使用度量視角作為來源

你可以用現有的度量視圖作為新的度量視圖來源:

version: 1.1

source: views.examples.source_metric_view

fields:
  - name: Order month
    expr: '`Order Month`'

measures:
  - name: Latest order month
    expr: MAX(`Order month`)
  - name: Latest order year
    expr: "DATE_TRUNC('year', MEASURE(`Latest order month`))"

當以度量視圖作為來源時,引用欄位與度量的組合規則相同。 請參閱 組合性。

使用 SQL 查詢作為來源

要使用 SQL 查詢,請直接在 YAML 中撰寫查詢文字:

version: 1.1

source: SELECT * FROM samples.tpch.orders o LEFT JOIN samples.tpch.customer c ON o.o_custkey
  = c.c_custkey

fields:
  - name: Order key
    expr: o_orderkey

measures:
  - name: Order Count
    expr: COUNT(o_orderkey)

Note

使用 SQL 查詢作為帶有 JOIN 子句的來源時,請對底層資料表設定主鍵與外鍵約束,並使用 RELY 該選項以達到最佳查詢效能。 請參見「 宣告主鍵、外鍵與唯一約束 」以及 「使用主鍵與唯一約束進行查詢優化」。

解析源碼中的陣列與映射

場、測度與連接皆作用於平坦的純量柱上。 如果你的來源資料有 ARRAY 欄位或 MAP 類型欄位,請先在查詢中將其解析為平面欄位 source ,再在指標視圖的其他地方參考。 有兩種轉換策略,取決於你是想要每個陣列元素一列,還是每個來源列只用一個值。 無論陣列是在頂層來源還是你加入的表格中,兩者都適用。 完整轉換函數集合請參見複雜 資料型態轉換 。

目錄中 samples 沒有任何資料集有陣列欄位,因此本節範例使用的 orders 是包含 line_items 結構體陣列的檢視。 請使用以下範例建立一個包含陣列欄位的視圖。 用你想寫入的目錄和架構來取代 catalog.schema 。 你必須擁有在該結構中建立物件的權限。

CREATE OR REPLACE VIEW catalog.schema.orders AS
SELECT
  o.o_orderkey,
  o.o_custkey,
  o.o_orderdate,
  o.o_orderstatus,
  collect_list(named_struct(
    'product_id', l.l_partkey,
    'quantity', cast(l.l_quantity as int)
  )) AS line_items
FROM samples.tpch.orders o
JOIN samples.tpch.lineitem l ON o.o_orderkey = l.l_orderkey
GROUP BY o.o_orderkey, o.o_custkey, o.o_orderdate, o.o_orderstatus;

將陣列壓平成行列

若要分析每個陣列元素作為獨立列,查詢中explode()使用 來source解包陣列。 每個元素會變成獨立的一列,而來源列的其他欄位則會對每個元素重複。 參見 從映射或陣列中爆破巢狀元素。

以下範例解包陣 line_items 列,使每個項目成為一列:

version: 1.1
source: |
  SELECT o_orderkey, o_custkey, item.product_id, item.quantity
  FROM catalog.schema.orders
  LATERAL VIEW explode(line_items) AS item

fields:
  - name: Product
    expr: product_id

measures:
  - name: Total quantity
    expr: SUM(quantity)
  - name: Line item count
    expr: COUNT(1)

在 中 source 爆破陣列會乘以來源列,因此像 的 COUNT(1) 聚合是計數陣列元素,而非原始列。 若要測量原始行且不向外展開,則將爆炸表建模為連接 one_to_many 。 參見 一對多連接。

將陣列聚合為單一值

若要將陣列縮減為每個來源列一個值而不改變列數,查詢時 source 需套用純量陣列函數,例如 aggregate()、 array_size()、 或 reduce()。 每個來源列保持其粒度,計算出的欄位可供欄位和度量使用。

以下範例計算每訂單的項目數量與陣列總數量 line_items :

version: 1.1
source: |
  SELECT o_orderkey, o_custkey,
    array_size(line_items) AS item_count,
    aggregate(line_items, 0, (acc, x) -> acc + x.quantity) AS total_quantity
  FROM catalog.schema.orders

measures:
  - name: Total quantity
    expr: SUM(total_quantity)
  - name: Average items per order
    expr: AVG(item_count)

由於原始查詢在度量檢視處理前先縮小陣列,來源每訂單保留一列,並照常跨順序進行聚合。

解析連接資料表中的陣列

同樣的規則適用於陣列存在你想加入的資料表,而不是在頂層來源中。 連接是處理平面欄位,因此在連接前,先解析連接資料表中自己的 source 子查詢陣列。 將 join source 寫成 SQL 查詢,將陣列平整或聚合,然後在產生的欄位上加入。 請參見 度量視圖中的連接。

以下範例以 為 customer 來源,並將 orders 視圖 cardinality: one_to_many與 連接起來。 連接 source 會將每個訂單的 line_items 陣列彙總為加入前的標量 total_quantity ,因此度量視圖可以依客戶加總,而不會重複客戶列:

version: 1.1
source: samples.tpch.customer

joins:
  - name: orders
    source: |
      SELECT o_orderkey, o_custkey,
        aggregate(line_items, 0, (acc, x) -> acc + x.quantity) AS total_quantity
      FROM catalog.schema.orders
    on: orders.o_custkey = source.c_custkey
    cardinality: one_to_many

fields:
  - name: Customer name
    expr: c_name

measures:
  - name: Total quantity
    expr: SUM(orders.total_quantity)
  - name: Order count
    expr: COUNT(orders.o_orderkey)

若將每個陣列元素視為連接表中的獨立列,則以相同方式將 在 explode() 連接 source 中的陣列平整。 請參見 將陣列扁平成行。

欄位

欄位(也稱為維度)是度量檢視資料欄,可在查詢時用於 SELECT、WHERE 和 GROUP BY 子句。 欄位可以是類別欄位,例如區域或狀態,或是未彙總的數字欄位,如價格或數量,這些欄位可以在查詢時彙總。 每個場表達式必須回傳一個純量值。 它可以參考來源資料中的欄位,或是指標檢視中先前定義的欄位。 每個領域包含兩個組成部分:

  • name:該柱的別名
  • expr: 一個 SQL 運算式,用於參考指標視圖中來源資料或先前定義的欄位

Warning

字串狀度量視圖欄位總是 STRING,即使來源欄位為 CHAR 或 VARCHAR。 由於 CHAR(n) 空間填充會遺失,比較結果可能會有所不同。 例如,column = 'COLLEGE' 符合來源資料表中的 CHAR(10) 值(該值以空格補齊),但不符合度量檢視欄位中的值。

措施

指標是產生結果的表達式,無需預設聚合層級。 它們必須使用聚合函數來表示。 要在查詢中參考測度,請使用函 MEASURE 式。 度量可以參考來源資料中的基底欄位、先前定義的欄位或先前定義的度量。 每個量值都包含下列元件:

  • name:該指標的別名
  • expr: 一個可包含 SQL 聚合函式的 SQL 聚合表達式

以下範例展示了分析訂單與收入資料的常見衡量模式。 這些範例使用 TPC-H 訂單表,該表包含訂單價格(o_totalprice)、客戶識別碼(o_custkey)、訂單金鑰(o_orderkey)、訂單日期(o_orderdate)及優先順序等級(o_orderpriority):

measures:
  # Simple count measure
  - name: Order Count
    expr: COUNT(1)

  # Sum aggregation measure
  - name: Total Revenue
    expr: SUM(o_totalprice)

  # Distinct count measure
  - name: Unique Customers
    expr: COUNT(DISTINCT o_custkey)

  # Calculated measure combining multiple aggregations
  - name: Average Order Value
    expr: SUM(o_totalprice) / COUNT(DISTINCT o_orderkey)

  # Filtered measure with WHERE condition
  - name: High Priority Order Revenue
    expr: SUM(o_totalprice) FILTER (WHERE o_orderpriority = '1-URGENT')

  # Measure using a field
  - name: Average Revenue per Month
    expr: SUM(o_totalprice) / COUNT(DISTINCT DATE_TRUNC('MONTH', o_orderdate))

如需聚合函數的清單,請參閱 聚合 函數。

套用篩選器

所有參考度量視圖的查詢都會有過濾器。 要在 UI 中定義過濾器,請參見 步驟 3:定義過濾器。

要在 YAML 定義中定義濾器,請寫一個布林運算式。 以下範例展示了常見的濾波器模式:

# Single condition
filter: o_orderdate > '2024-01-01'

# Multiple conditions
filter: o_orderdate > '2024-01-01' AND o_orderstatus = 'F'

# IN clause
filter: o_orderstatus IN ('F', 'P') AND o_orderdate >= '2024-01-01'

聯接操作

指標檢視支援聯結,可使用相關資料表中的屬性來擴充來源資料。 你可以建模星型結構(事實表與維度表相連)、雪花結構(多層次維度連接)以及一對多關係(從維度來源展開事實擴展)。 關於連接類型、基數、結構模式及限制的詳細資訊,請參見 度量視圖中的連接。

要在 UI 中定義連接,請參見 步驟 2:新增連接。 要在 YAML 定義中定義 join,請使用以下章節的模式。

Note

合併的資料表無法包含 ARRAY 或 MAP 輸入欄位。 若要解析陣列或映射到平面欄位,請參見 原始碼中的解析陣列與映射。

模型星狀結構描述

在星型架構中,source 是事實數據表,並使用 LEFT OUTER JOIN 聯結一或多個維度數據表。 度量檢視會根據所選欄位和度量,結合特定查詢所需的事實表與維度表。

請使用 on 子句(布林表達式)或 using 子句(共用欄位名稱)來指定連接欄位。 連接必須遵循多對一關係。 在多對多的情況下,引擎會從聯結的維度資料表中選取第一個相符的資料列。

以下範例將 orders (事實表)與 customer (維度表)連接,並將客戶屬性暴露為欄位。 設定 rely.at_most_one_match: true 宣告連接為多對一(每個訂單恰好有一位客戶),這讓引擎能優化查詢,過濾連接表中的欄位。

Warning

只有在關係為多對一時,才設定 at_most_one_match: true。 此特性在執行時不會被驗證。 若連接產生扇出,度量會回傳錯誤結果。

請參見使用 rely最佳化聯結。

version: 1.1
source: samples.tpch.orders

joins:
  - name: customer
    source: samples.tpch.customer
    on: source.o_custkey = customer.c_custkey

fields:
  - name: Customer name
    expr: customer.c_name

measures:
  - name: Total revenue
    expr: SUM(o_totalprice)

YAML 語法和格式

計量檢視定義遵循標準 YAML 表示法語法。 請參閱 Metric 視圖 YAML 語法參考, 了解所需的語法與格式。

最佳做法

建立度量視圖模型時,請使用下列準則:

  • 建模原子測度:首先定義最簡單的測度(例如, SUM(revenue), COUNT(DISTINCT customer_id))。 利用可組合性建立複雜的度量。
  • 標準化欄位值:使用轉換(如 CASE 對帳單)將資料庫代碼轉換為明確的企業名稱(例如,將訂單狀態「O」轉換為「Open」,「F」轉換為「已完成」)。
  • 定義範圍並搭配篩選器:如果一個指標檢視只應該包含已完成的訂單,請在指標檢視中設定該篩選條件,避免使用者不小心包含不完整的資料。
  • 使用明確命名:指標名稱應對業務使用者易於辨識(例如,應用「客戶終身價值」代替 cltv_agg_measure)。
  • 獨立時間欄位:包含細緻時間欄位(如「訂單日期」)及截短時間欄位(如「訂單月份」或「訂單週」),以支援細節層級與趨勢分析。

其他資源