彙總型別:rollup
用途
rollup 沿著 link 對一組相關紀錄做聚合,例如在客戶表顯示該客戶所有訂單的總金額,或在專案表計算工作項目數。它適合「多筆來源濃縮成一個指標」,而不是複製某一筆目標列的欄位。
建立 schema
先建立 link,再送出 columns.create body。以下 outgoing rollup 沿「訂單」link 加總目標表的「金額」欄:
{
"name": "訂單總金額",
"type": "rollup",
"link_field": "訂單",
"aggregation": "sum",
"target_column": "金額",
"description": "目前連結訂單的總金額"
}link_field 與 target_column 都接受顯示名稱或 col_<hex> 內部鍵;伺服器解析後以內部鍵保存,使欄位改名不會破壞依賴。
方向與聚合
direction 省略時為 "outgoing":從本列的 link_field 走到目標列。"incoming" 則對另一張來源表中「連回本列或與本列 link 相符」的紀錄聚合,改用 source_table_id 與 1–3 組 match pair,不能再設定 link_field。每一組 pair 把來源表的一個 link 欄位對應到本表中、指向同一張表的 cardinality-one link 欄位;若來源欄位連回本表自己,則對應到 "$self"。未知的 source_table_id,或超出 link 使用的同公司向上範圍矩陣者,會被拒絕(columns.create 回 400,columns.preview 回 valid: false),訊息一律是 source table not found or not accessible,而且沒有提示。
aggregation | target_column | 可用目標型別 | 空集合 |
|---|---|---|---|
count | 不可設定 | 不讀值欄 | 0 |
count_distinct | 必填 | 儲存型純量欄 | 0 |
sum / avg | 必填 | integer、float、decimal | null |
min / max | 必填 | integer、float、decimal、date、datetime | null |
另有一個單層例外:需要 target_column 的聚合可以指向數值 formula,但該目標公式只能引用同表的儲存型數值欄,不能再引用 rollup、lookup、其他 formula 或跨表欄位,而且輸出必須是數字。以 decimal 為輸出的目標公式限制更窄:它只能引用儲存型 integer 與 decimal 欄位,且只能使用精確運算(+、-、*、DECIMAL、QUANTIZE、DIVIDE)。伺服器會把這一層公式內嵌到聚合中。
對 decimal 欄位或 decimal 目標公式做 avg,還必須設定 result_scale(0 到 18 的整數)與 rounding_mode(half_even、half_up、down、floor 或 ceiling)。兩個欄位必須一起提供,其他任何 rollup 設定它們都會被拒絕:
{
"name": "平均單價",
"type": "rollup",
"link_field": "訂單明細",
"aggregation": "avg",
"target_column": "單價",
"result_scale": 2,
"rounding_mode": "half_even"
}此範例假設 單價 是 decimal 欄位:對目標既不是 decimal 欄位、也不是 decimal 輸出公式的 avg 設定同樣的 result_scale 與 rounding_mode,會以 400 拒絕(rounding options apply only to decimal avg rollups)。
可選的 filter 會在聚合前篩選來源列。它最多接受 10 個 predicate {column, op, value},每一個都作用在被聚合資料表的儲存純量欄位上(outgoing rollup 是目標表,incoming rollup 是來源表)。op 是 eq、neq、gt、gte、lt、lte、in、contains、is_null 或 is_not_null:gt、gte、lt、lte 需要 integer、float、decimal、date 或 datetime 欄位,contains 需要 string 或 text 欄位,principal 欄位與紀錄 id 只接受 eq、neq、in、is_null 與 is_not_null,in 接受最多 100 個純量值的非空清單,is_null / is_not_null 不帶值。每個值都必須符合其欄位的型別,$me 或 $today 之類的 token 會被拒絕。超過 10 個 predicate、未知的 op,或不符合該 op 的值形狀是 422;未知或非純量的欄位、欄位型別不支援的運算子,或型別錯誤的值,在 columns.create 是 400,在 columns.preview 則是 valid: false。與 decimal 欄位比較的值是小數字串,例如 "100.50"。
合法與不合法的值
rollup 是唯讀欄。建立或更新紀錄時,合法做法是完全省略它:
{
"data": {
"客戶名稱": "青鳥設計"
}
}即使數字看起來正確,也不能自行寫入計算結果:
{
"data": {
"客戶名稱": "青鳥設計",
"訂單總金額": 3880.5
}
}設定面也有明確限制。count 帶 target_column、其他任何聚合缺 target_column、rollup 沒有 aggregation、outgoing rollup 缺 link_field 或帶了 source_table_id 或 match、incoming rollup 缺 source_table_id 或 match、帶了 link_field 或超過 3 組 match pair,以及任何 rollup 帶 expression、pick、fallback、target_table_id 或 cardinality,都會通不過 ColumnCreate 驗證,因此 columns.create 與 columns.preview 回 422。link_field 指到非 link 欄,或 target_column 不存在、型別不符合該聚合,在 columns.create 是 400,在 columns.preview 則是 valid: false。
顯示與回傳
讀取紀錄時,rollup 值會併入 data 並使用顯示名稱:
{
"data": {
"客戶名稱": "青鳥設計",
"訂單總金額": 3880.5
}
}count / count_distinct 回數字;對 integer 或 float 的 sum / avg / min / max 回數字,日期的 min / max 回固定格式字串。對 decimal 欄位則回精確的小數字串:sum、min、max 以欄位的 scale 表示,avg 以 result_scale 表示。對 decimal 目標公式,sum、min、max 回沒有尾端零的純小數字串,avg 則使用 result_scale。空集合的 count 是 0,但沒有讀取權限或依賴失效時是 null,兩者不可混為一談。
注意事項
- rollup、lookup、formula 每表合計最多 20 欄;link 不計入這個上限。
- Rollup 設定建立後不可變更。
PATCH columns/{column_id}只能修改name或description;要改 direction、link/source/match、aggregation、target、filter 或型別,必須刪除並重建欄位。 - rollup 不可
required、不可有default_value或max_length,記錄 payload 的任何非null值都會以唯讀錯誤拒絕。 - 呼叫者無權讀取被聚合表時,cell 為
null,欄位回應會標記restricted: true;即使 aggregation 是 count 也不回 0。 target_column或link_field被刪除時,既有欄位會降級成null;正常刪欄流程會先用 409 依賴衝突阻擋這種情況。- 對 decimal 目標公式的 rollup 會以精確運算聚合。只要任何一列聚合時溢位或遇到無效運算(例如
DIVIDE除以 0),會呈現該 rollup 的讀取單筆、列表、搜尋或 XLSX 匯出,都會以400ct.numeric_overflow: decimal formula aggregate exceeds the exact SQL domain或ct.numeric_invalid: decimal formula aggregate contains invalid arithmetic失敗,而不是顯示null;建立或更新帶有該 cell 的紀錄也一樣:它的回應在 commit 之前就會渲染,所以寫入會被回滾。CSV 匯出在下載開始前只渲染前 1,000 列,因此更後面的列出錯時,會中斷已經開始的下載,而不是回400;預覽計算欄(columns.preview)時,若五筆樣本列之一遇到這個錯誤,會回400,並以字串detail帶出相同的 decimal 計算錯誤。透過computed_filters或計算欄sort_by篩選或排序該 rollup 的請求,會在渲染任何內容之前先檢查查詢範圍內的每一列,並改以400ct.numeric_overflow: computed decimal cannot be evaluated exactly或ct.numeric_invalid: computed decimal cannot be evaluated exactly失敗。 - 在本次稽核的後端 source 中,
count_distinct、incoming、filter 與全部 v1.1 計算功能都不再受條件控制,舊的COMPUTED_COLUMNS_V11gate 已移除。部署環境仍可能執行較舊的 source revision,因此把這份 source contract 當成 live-environment 證據之前,必須另行核對 deployed SHA。
試試看
用連結與彙總流程精靈建立可讀取的 rollup,再用 columns.preview 在落地前查看前 5 筆 sample。