首页 / 聚合
MAX_BY 取最大值对应的列
MAX_BY(x, y) 返回 y 最大的那一行的 x,例如“每个用户最近一次下单的门店”。MaxCompute、Hologres、StarRocks、Doris 和 Spark 都支持;Hive 和 Flink 没有,要用 ROW_NUMBER 窗口函数改写。y 相同时返回哪一行不确定。
各引擎写法
| 引擎 | 支持 | 写法 | 说明 | 依据 |
|---|---|---|---|---|
| MaxCompute | 支持 | MAX_BY(valueToReturn, valueToMaximize) |
valueToMaximize 为 NULL 的行不参与计算。多行并列最大时随机返回其中一行。 | 官方文档 |
| Hologres | 支持 | MAX_BY(x, y) |
V1.3.36 起提供,同时有 MIN_BY。 | 官方文档 |
| StarRocks | 支持 | max_by(x, y) |
2.5 起提供。y 为 NULL 的行被忽略,并列时返回最先遇到的 x。y 不能是 bitmap、hll 等不可排序的类型。 | 官方文档 |
| Doris | 支持 | MAX_BY(expr1, expr2) |
返回 expr2 最大时对应的 expr1。文档没有说明 NULL 和并列的处理。 | 官方文档 |
| Hive | 需改写 | ROW_NUMBER() OVER (PARTITION BY ... ORDER BY y DESC) = 1 |
函数手册中没有 MAX_BY,用窗口函数取每组第一行。 | 官方文档 |
| Spark SQL | 支持 | max_by(x, y[, k]) |
传入 k 时返回 y 最大的前 k 个 x 组成的数组,k 最大 100,000。y 全为 NULL 时返回 NULL。 | 官方文档 |
| Flink SQL | 需改写 | ROW_NUMBER() OVER (PARTITION BY ... ORDER BY y DESC) = 1 |
内置函数中没有 MAX_BY 或 ARG_MAX,用 ROW_NUMBER 窗口函数改写。 | 官方文档 |
迁移注意事项
- 并列最大时结果不确定:MaxCompute 随机返回一行,StarRocks 返回最先遇到的一行。需要稳定结果时,改用 ROW_NUMBER 并在 ORDER BY 中加上唯一的次排序列。
- MAX_BY 一次只能取一列。需要同时取最大值所在行的多列时,ROW_NUMBER 写法更合适,也不用为每列各写一次 MAX_BY。
- 参数顺序是“要返回的列在前,比较大小的列在后”,写反了不会报错,但结果完全不对。
示例
每个用户最近一次下单的门店
SELECT user_id, MAX_BY(store_id, order_time) FROM orders GROUP BY user_id;SELECT user_id, max_by(store_id, order_time) FROM orders GROUP BY user_id;SELECT user_id, store_id FROM (
SELECT user_id, store_id, ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY order_time DESC) AS rn
FROM orders
) t WHERE rn = 1;