LIMIT BY 是干什么的
LIMIT BY 对每个分组各取前若干行:写法是 LIMIT n BY 表达式,分组内按当前 ORDER BY 的顺序取前 n 行。它比"先全量排序再在应用层按组过滤"更贴近业务直觉,是 ClickHouse 里实现"每个维度取最近 N 条""每组取最高 N 条"的常用手段。
结果顺序怎么控制
LIMIT BY 只保证每组取到指定行数,不保证组与组之间的输出顺序;需要稳定展示时要在外层再套一层 ORDER BY 或子查询。语句末尾还可以再写一个普通 LIMIT 限制总返回行数,它与 BY 后面的 n 是两件不同的事。
基本信息
| 语法 | LIMIT [offset, ]n BY expr1 [, expr2 ...] |
|---|---|
| 语义 | 分组内按当前 ORDER BY 顺序取前 n 行 |
| 叠加写法 | 末尾可再写普通 LIMIT 限制总返回行数 |
| 实现方式 | 按分组在内存里各保留若干行,分组多时占用内存 |
| 适用版本 | ClickHouse 各主流版本均支持 |
示例
示例
-- 每个 region 取最近 3 条记录
SELECT region, ts, value
FROM metrics
ORDER BY ts DESC
LIMIT 3 BY region;
-- 分组取前 3,再限制总返回 20 行
SELECT region, ts, value
FROM metrics
ORDER BY ts DESC
LIMIT 3 BY region
LIMIT 20;
-- 分组键可以是表达式:按天取最早的一条
SELECT toDate(ts) AS d, argMin(value, ts) AS first_value
FROM metrics
GROUP BY d
ORDER BY d
LIMIT 1 BY d;典型使用场景
- 每组取最近 N 条:设备最新上报、用户最近订单
- 每组取最大或最小 N 条:各门店销售额前几名
- 抽样核对:每个分类各抽若干条做人工检查
- 去重取一条:按业务键取最新版本记录
- 报表明细:每个维度只展示前几条代表记录
写法与语义
| 写法 | 作用 | 注意 |
|---|---|---|
| ORDER BY ... LIMIT n BY k | 分组取前 n 行 | 组内顺序由 ORDER BY 决定 |
| LIMIT offset, n BY k | 组内跳过 offset 行再取 n 行 | offset 是组内偏移 |
| 外层再写 LIMIT m | 限制总返回行数 | 与 BY 的 n 不是一回事 |
| 配合 GROUP BY | 先聚合再取每组前若干 | 两种分组的语义不要混淆 |
LIMIT BY 不保证按组输出,外层再写 ORDER BY 才有稳定顺序;把它当成全局去重会得到非预期结果,因为总行数可以是每组保留行数乘以组数。
对高基数列做 LIMIT BY 会生成大量分组,每组都要保留若干行,内存与耗时随之上升;分组基数不可控时应先用 WHERE 把范围缩小。