← 返回 技术博客

技术文章

把复杂分析变成函数调用:HENGSHI SENSE 高级计算函数的正确用法

留存、累计、同期对比、分区汇总和条件聚合,业务上常是一句话,落实到查询时却涉及时间轴、图表分组、筛选器和数据源。HENGSHI SENSE 用高级计算函数、聚合函数和图表高级计算承载这些高频问题。函数不能代替业务口径,却能把对象、粒度和过滤规则固化为可复用的指标表达式。本文以 6.2 函数手册为语义基线,并参照已公开的 6.3.2 与 6.2.5 版本说明,说明实际用法和边界。

2026/10/13技术博客HENGSHI6 分钟阅读
HQLHENGSHI SENSE高级计算

Article body

正文

摘要: 留存、累计、同期对比、分区汇总和条件聚合,业务上常是一句话,落实到查询时却涉及时间轴、图表分组、筛选器和数据源。HENGSHI SENSE 用高级计算函数、聚合函数和图表高级计算承载这些高频问题。函数不能代替业务口径,却能把对象、粒度和过滤规则固化为可复用的指标表达式。本文以 6.2 函数手册为语义基线,并参照已公开的 6.3.2 与 6.2.5 版本说明,说明实际用法和边界。

1 先定上下文,再写函数

高级计算不是任意 SQL 片段。时间函数依赖图表时间维度,预计算函数受图表分组与小计影响,聚合函数决定输入行如何收敛。定义指标前,应明确分析对象、基础事件、统计粒度、时间端点,以及条件来自页面筛选还是指标自身。这样,指标换图、换维度或出现小计后,团队仍能判断它是否回答同一个问题。

下文表达式使用按官方函数语义改写的教学字段;落地时,将 {user_id}、{event_time} 等替换为实际模型字段,并用小样本核对输出粒度、筛选和展示格式。本文不把教学表达式称为线上实测结果或性能验证。函数页也没有给出“每个高级函数在每个数据源均完整支持”的总矩阵,字段类型、日期表达式、连接类型和函数组合都要在目标环境验证。

2 留存与连续活跃:日期轴和端点不可省略

retention(expression, date expression, lowExpr, upperExpr, ...) 返回时间维度下的留存或活跃对象数。日期表达式必须进入图表维度;在 summarize 中使用时,也必须作为非聚合参数。upperExpr 要比业务实际结束时间晚一天。存在/排除条件有四个可选参数,必须一起出现且顺序固定。它输出的是计数,不会自动成为留存率,分母还要由指标口径明确。

retention({user_id}, day({event_time}),
  add_day(day({event_time}), 1),
  add_day(day({event_time}), 8))

continuous_retention(expression, date expression, lowExpr, upperExpr, period) 返回连续活跃数。period 只支持 day、week、month、quarter、year,日期轴与结束端点规则相同。它比“窗口内出现过一次”严格,因此要先定义用户标识、去重规则和活跃事件。连续活跃率还需要确定分母,不能只改显示格式。

static_retention、static_retention_rate、static_continuous_retention 适合按渠道、产品线等非时间维度输出。static 指输出分组非时间,并不表示不需要日期:函数仍要求日期表达式、计算区间和比较区间;两个结束日期要比实际结束时间晚一天,连续静态函数还需 period。

static_retention({user_id}, {event_time},
  '2026-01-01', '2026-02-01',
  '2026-02-01', '2026-03-01')

3 累计、对比和移动:签名决定时间语义

date_accumulate(function1(function2(expression)), date expression, reset period) 先做基础聚合,再对时间序列累计。外层可为 sum、avg、min、max;内层还可为 percentile、count、distinct_count;reset period 可为 hour、day、week、month、quarter、year。它只能用于新增指标或 API 查询,并要求日期表达式进入图表或 summarize 分组。月累计、季累计和年累计的差别来自重置周期,财务期间或非自然周应先在日期模型中定义。

date_accumulate(sum(sum({sales_amount})),
  day({order_time}), 'month')

date_compare(function(expression), date expression1, date expression2) 用明确的日期表达式取得对比值。previous(function(expression), period, delta) 则随图表时间轴计算,period 可为 year、quarter、month、week、day、hour,省略时采用图表最小时间粒度。日期不连续时,手册示例返回空值,因此 previous 不是“上一行”的同义词。

date_shift(function1(function2(expression)), date expression, lowExpr, upperExpr) 按时间序列逐项推移,用数值型前后偏移量做移动统计。手册没有把它定义为自动补齐缺失日期的日历窗口;时间轴有断档时,应核对当前项和边界结果。性能应在代表性数据、分组基数、并发和连接配置上实测,不能承诺固定收益。

4 预计算、跨数据集和部分汇总:显式写出分组

函数语义
calculate(ARG1, [ARG2], ...)预计算值会随小计变化;ARG2 可省略,给出时删除图表分组中的该字段。
calculatep(ARG1, [ARG2], ...)预计算值不受小计影响;ARG2 同样用于删除指定图表分组。
calculatex(ARG1, ARG2, ...)不受维度控制且可用于维度;ARG2 必填,必须显式写出预计算所需分组。

三者用于先计算表达式、再参与图表计算,常见于新增指标或图表过滤;作为指标时,外层还要有合适的聚合函数。calculatex 不是无参“忽略所有维度”。对排名、占比和总分母,应分别检查明细、分组和小计行。

calculatex(rank() OVER (ORDER BY sum({sales_amount}) ASC),
  {category}) < 4

lookupvalue(ARG1, ARG2, ARG3) 只能用于新增指标:ARG1 是非关联数据集上的聚合表达式,ARG2 是该数据集的匹配表达式,两处字段都必须带数据集 ID;ARG3 是当前图表的匹配表达式,且必须与一个图表维度相同。它不是任意原始字段的单值 VLOOKUP。应让 ARG1 在 ARG2 粒度上得到业务上唯一、可解释的聚合结果,并验证重复键和空匹配。

lookupvalue(sum({{2}}.{purchase_amount}),
  year({{2}}.{purchase_date}), year({order_date}))

rollup_value(ARG) OVER ([PARTITION BY expr1]) 的 ARG 是聚合表达式。OVER() 为总汇总,PARTITION BY 为部分维度汇总;文档签名没有排序或行窗口。它可作为月度总额等占比分母,前提是分区字段与业务粒度一致。

top_n 和 bottom_n 在指定分组、排序下保留 N 个 field1 值,并将未保留值替换为同类型 constant1,不删除其他行。custom_filters(expression, [{field1}, {field2}], condition) 的第一参必须是基础聚合;第二参为 null 时保留上文过滤器,为 [] 时删除全部上文过滤器,为字段数组时删除使用这些字段的过滤器,第三参再增加条件。因此它不只是普通条件聚合。

5 聚合函数:条件、排序、空值与精度都有范围

条件聚合写在聚合表达式后:sum({sales_amount}) FILTER (WHERE {order_status} = 'completed')。它只限定该度量输入,页面筛选器仍会影响该度量,除非再用上下文函数调整。WITHIN GROUP (ORDER BY ...) 只支持 first、last、mode、percentile、string_agg,不能泛化给所有聚合。未排序的 first、last 值不固定;Oracle 上 string_agg 必须带 WITHIN GROUP。

空值也不能一概而论:count({field}) 不计 null,regr_count(ARG1, ARG2) 只计两个输入都非空的行;max_by、min_by 的比较值并列时会随机取一个。比率指标应在定义中约定分母为零时返回空值、零值或不展示。

去重有数据源差异。distinct_count 在 Impala 上是近似去重;精确去重可用 exact_distinct_count,手册当前仅列 Impala 适用,且它只能作为聚合函数使用,不能当普通字段公式或子查询字段。不要将这一差异推广到其他引擎。

6 图表高级计算和指标复用:支持矩阵也有边界

图表高级计算覆盖百分比、百分位数、同环比、累计、移动、重复、留存、活跃和窗口计算。该矩阵针对这九类图表能力,不是全部 HQL 函数逐函数的兼容承诺。手册列出 Engine、PostgreSQL、Oracle、MySQL 8、SQL Server 2017-CU8、Redshift、Impala、Presto、Greenplum、Hive、Spark SQL、DB2 均支持;MaxCompute 不支持百分位数;TiDB、MySQL 5、MongoDB 不支持图表高级计算。Engine 指开启引擎的数据集。

同环比、累计、移动、活跃、留存要求数据集存在日期字段;时间维度移除或选择天、周、月、季、年以外的聚合方式,相关高级计算会取消。周按 ISO 8601 划分,新增维度会作为过滤条件影响计算。复用指标时,应检查日期维度、小计、默认筛选、分母和空值规则。

公开版本说明显示 6.3.2 和 6.2.5 均在 2026 年 9 月 23 日发布。6.2 是本文函数语义的手册基线,不能笼统称为当前最新版本;升级或跨版本迁移时,应回归验证关键图表结果、格式和筛选交互。

6.1 用分布、相关和回归聚合补足诊断能力

高级分析并不只处理时间序列。聚合函数提供 avg、median、percentile、mode、标准差和方差,用于从均值之外观察分布与波动。百分位数的参数 P 按手册定义为 0 到 1 之间的小数;例如用 percentile({response_seconds}, 0.5) 描述中位位置时,仍要在指标名称中说明统计对象、筛选范围和时间粒度。mode() WITHIN GROUP (ORDER BY ...) 可按指定排序取出现频次最高的值,频次并列时返回第一个值,因此同样需要检查排序字段是否符合业务解释。

corr(ARG1, ARG2) 计算两个数值列的相关系数,covar_pop 与 covar_samp 分别计算总体和样本协方差。回归函数可进一步输出拟合信息:regr_slope(ARG1, ARG2) 和 regr_intercept(ARG1, ARG2) 的拟合关系按 (ARG2, ARG1) 确定,regr_r2 给出相关系数平方,regr_count 给出两个输入均非空的样本数。以 regr_slope({conversion_amount}, {ad_cost}) 评估投入与转化金额的线性关系时,要先确认字段顺序、异常值处理和样本量;相关或回归结果不能单独证明因果关系。

这类函数适合在运营质量、价格波动、用户行为和指标监测中补充解释维度。可先用 count 与 regr_count 核对有效样本,再查看分位数、均值与离散程度,最后再解读相关或回归参数。将统计口径同维度、筛选和时间范围一并封装为指标,图表间复用时才不会出现同名指标含义不同。

6.2 把验证后的表达式沉淀为业务指标

新增指标适合承载已经确认的高级表达式,图表只负责选择维度、展示方式和交互筛选。一个可复用定义至少应包含:字段来源与数据集 ID、基础聚合、时间粒度、分组或分区、默认过滤规则、空值和除零处理方式,以及展示格式。把这些说明和公式保存在同一指标定义中,能减少在多张图表中复制表达式后产生的口径漂移。

7 用真实结果验证口径和性能

7.1 验收应同时检查数值、交互和数据源

验收时可先准备少量可人工核算的样本,覆盖窗口起止、重复事件、缺失日期、空值、并列排序和分母为零。随后在目标数据源上比较指标与人工结果,再分别改变日期粒度、增加维度、显示小计和切换筛选器,检查结果是否符合函数定义。最后使用代表性数据量和并发记录响应时间、返回行数和结果抽样。这个过程既能发现公式问题,也能发现数据类型、时区、数据源能力或图表交互带来的差异。

  • 为留存、累计和同比记录对象字段、事件定义、日期粒度、端点和分母。
  • 为 calculatex 明确写出分组;为 lookupvalue 验证匹配键唯一性;为 rollup_value 验证分区和分母粒度。
  • 为 FILTER、WITHIN GROUP、空值和除零写出规则;Impala 去重要确认近似或精确。
  • 在代表性时间范围、数据量、并发、分组基数和连接上测试响应时间与结果抽样,并记录环境、查询耗时和异常结果。用这些证据判断函数组合与数据源配置是否满足实际业务需要。

高级函数把复杂分析压缩为较短的表达式,可信度仍来自可复核的业务口径、清楚的数据源范围和真实数据上的验证。

HENGSHI SENSE

丰富的资源 完整的生态

邀您成为衡石伙伴

立即加入

企业级部署、产品集成与试用咨询均可快速响应