首页/数据/NoSQL 速查/LIMIT BY 分组取前 N
ClickHouse56 条

LIMIT BY 分组取前 N

LIMIT BY 对每个分组各取前若干行:常配合 ORDER BY 实现按维度取最近/最高记录,比排序后过滤的结果更符合业务直觉。

NoSQL 速查数据更新于 2026-10-13

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 把范围缩小。

易错点

  • 分组列既不在 SELECT 里也不在分组表达式内时,容易得到非预期的分组结果
  • 对高基数列做 LIMIT BY 会生成大量分组,注意内存占用与耗时
  • 把 LIMIT BY 当全局去重使用会误判结果条数,它是每组各取 n 行
  • 没有外层 ORDER BY 时组间顺序不稳定,直接输出给报表会出现顺序忽上忽下

数据来源与参考

  • ClickHouse Docs: LIMIT BY clause
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌