> ## Documentation Index
> Fetch the complete documentation index at: https://private-7c7dfe99-parallel-read-in-order-multi-part.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

> LIMIT 子句文档

# LIMIT

`LIMIT` 子句用于控制查询结果返回的行数。可按数量和偏移量选择行，也可根据通过 [`LIMIT ... AFTER ... UNTIL`](#limit-after-until) 确定行范围起止的条件选择行。

## 基本语法

**选择前几行：**

```sql theme={null}
LIMIT m
```

返回结果中的前 `m` 行；如果结果少于 `m` 行，则返回全部记录。

**TOP 的另一种语法 (兼容 MS SQL Server) ：**

```sql theme={null}
-- SELECT TOP number|percent column_name(s) FROM table_name
SELECT TOP 10 * FROM numbers(100);
SELECT TOP 0.1 * FROM numbers(100);
```

这相当于 `LIMIT m`，可用于兼容 Microsoft SQL Server 的查询语法。

**带偏移量的 SELECT：**

```sql theme={null}
LIMIT m OFFSET n
-- or equivalently:
LIMIT n, m
```

跳过前 `n` 行，然后返回后续 `m` 行。

在这两种形式下，`n` 和 `m` 都必须是非负整数。

**按条件选择范围：**

```sql theme={null}
LIMIT [n] AFTER start_expr [UNTIL end_expr]
LIMIT [n] UNTIL end_expr
```

返回从 `start_expr` 为 true 的第一行起，到该起始位置或其之后 `end_expr` 为 true 的第一行之前的行；若省略 `AFTER`，则从 stream 的开头起；`n` 限制该范围的长度。`AFTER start_expr ALL` 会在每个匹配行处开启一个范围。请参阅下方的 [LIMIT ... AFTER ... UNTIL](#limit-after-until)。

## 负数限制

使用负值从结果集的*末尾*选取行：

| 语法 | 结果 |
| - | - |
| `LIMIT -m` | 最后 `m` 行 |
| `LIMIT -m OFFSET -n` | 跳过最后 `n` 行后，再取最后 `m` 行 |
| `LIMIT m OFFSET -n` | 跳过最后 `n` 行后，再取前 `m` 行 |
| `LIMIT -m OFFSET n` | 跳过前 `n` 行后，再取最后 `m` 行 |

`LIMIT -n, -m` 语法等同于 `LIMIT -m OFFSET -n`。

## 分数限制

使用 0 到 1 之间的小数值来选取一定比例的行：

| Syntax | Result |
| - | - |
| `LIMIT 0.1` | 前 10% 的行 |
| `LIMIT 1 OFFSET 0.5` | 位于中间的那一行 |
| `LIMIT 0.25 OFFSET 0.5` | 第三四分位数对应的行 (跳过前 50% 后，再取 25% 的行) |

<Note>
  * 分数必须是大于 0 且小于 1 的 [Float64](/zh/reference/data-types/float) 值。
  * 非整数的行数会向上取整到下一个整数。
</Note>

## 组合不同的 LIMIT 类型

你可以将普通整数与小数或负偏移量混合使用：

```sql theme={null}
LIMIT 10 OFFSET 0.5    -- 10 rows starting from the halfway point
LIMIT 10 OFFSET -20    -- 10 rows after skipping the last 20
```

[范围形式](#limit-after-until)只能与普通行数结合使用：`LIMIT 3 AFTER start_expr` 从范围起点开始最多获取三行。`OFFSET`、小数和负数计数以及 `WITH TIES` 均不能与 `AFTER` 或 `UNTIL` 一起使用。同一查询中，[`LIMIT BY`](/zh/reference/statements/select/limit-by) 子句可以位于范围之前，且 [`limit`](/zh/reference/settings/session-settings/other#limit) 设置仍会限制结果。

## LIMIT ... WITH TIES

`WITH TIES` 修饰符会包含与限制结果中最后一行具有相同 `ORDER BY` 值的其他行。它仅适用于计数和偏移量限制，且不能与[范围形式](#limit-after-until)结合使用。

```sql theme={null}
SELECT * FROM (
    SELECT number % 50 AS n FROM numbers(100)
) ORDER BY n LIMIT 0, 5
```

```response theme={null}
┌─n─┐
│ 0 │
│ 0 │
│ 1 │
│ 1 │
│ 2 │
└───┘
```

使用 `WITH TIES` 时，所有与最后一个值相同的行都会包含在结果中：

```sql theme={null}
SELECT * FROM (
    SELECT number % 50 AS n FROM numbers(100)
) ORDER BY n LIMIT 0, 5 WITH TIES
```

```response theme={null}
┌─n─┐
│ 0 │
│ 0 │
│ 1 │
│ 1 │
│ 2 │
│ 2 │
└───┘
```

第 6 行也会被包含在内，因为它与第 5 行的值相同 (`2`) 。

使用 `OFFSET` 关键字指定偏移量时，情况也是如此：

```sql theme={null}
SELECT * FROM (
    SELECT number % 50 AS n FROM numbers(100)
) ORDER BY n LIMIT 3 OFFSET 2 WITH TIES
```

```response theme={null}
┌─n─┐
│ 1 │
│ 1 │
│ 2 │
│ 2 │
└───┘
```

跳过前 2 行并取 3 行通常会返回 `1, 1, 2`，但由于第二个 `2` 与最后一行并列，因此也会包含在结果中。

`WITH TIES` 也适用于负数限制和偏移量。它会包含与所选第一行具有相同 `ORDER BY` 值的其他行：

```sql theme={null}
SELECT number % 3 AS n FROM numbers(15)
ORDER BY n LIMIT -4 OFFSET -3 WITH TIES
```

```response theme={null}
┌─n─┐
│ 1 │
│ 1 │
│ 1 │
│ 1 │
│ 1 │
│ 2 │
│ 2 │
└───┘
```

不使用 `WITH TIES` 时，结果将是 `1, 1, 2, 2`。使用 `WITH TIES` 时，会额外包含三个值为 `1` 的行，因为它们与选中的第一行并列。

此修饰符可与 [`ORDER BY ... WITH FILL`](/zh/reference/statements/select/order-by#order-by-expr-with-fill-modifier) 修饰符结合使用。

## LIMIT ... AFTER ... UNTIL (按条件划定范围)

您可以将结果限制为两个边界条件之间的某个行*范围*：

```sql theme={null}
LIMIT [n] AFTER start_expr [UNTIL end_expr]
LIMIT [n] AFTER start_expr ALL [UNTIL end_expr]
LIMIT [n] UNTIL end_expr
```

* `AFTER start_expr`：从 `start_expr` 为 true 的第一行开始输出 (包含该行) 。
* `AFTER start_expr ALL`：输出所有从 `start_expr` 为 true 的位置开始的匹配范围的并集；当范围重叠时，不会重复输出行。
* `UNTIL end_expr`：每个范围在其起始位置或之后 `end_expr` 为 true 的第一行之前结束 (不包含该行) 。
* `n`：可选的行数。不使用 `ALL` 时，它表示单个已打开范围的最大长度。使用 `AFTER ... ALL` 时，它表示*每个*已打开范围的长度，因此结果行总数可能超过 `n` (例如，`LIMIT 2 AFTER number IN (2, 6) ALL` 最多可返回四行) 。若要限制结果行总数，请使用 `limit` 设置；该设置会在范围处理后作为全局限制应用。

流顺序 (即读取行的顺序) 决定“第一个”匹配；可使用 `ORDER BY` 对其进行控制。

在范围开始之前出现的 `UNTIL` 匹配不起作用。如果两个条件都匹配起始行，则该范围为空。如果在起始位置或之后没有出现 `UNTIL` 匹配，该范围会一直延续到其行数 `n` 或 stream 末尾。使用 `AFTER ... ALL` 时，在前一个范围结束后，后续的 `AFTER` 匹配可以打开新的范围。

使用 `AFTER` 且不使用 `ALL` 时，范围步骤会持续对 `AFTER` 求值，直到找到包含起始匹配的 chunk。随后，只要范围仍处于打开状态，就会在该 chunk 及后续 chunk 中对 `UNTIL` 求值。表达式是按整个 chunk 求值的，因此在起始 chunk 内，位于起始位置之前的行仍可能被求值 `UNTIL`。

如果 `UNTIL` 中包含诸如 `rowNumberInAllBlocks` 这类 stateful function，或在查询中具有 non-deterministic 行为的函数，则会从第一个 chunk 开始求值，以保持这些函数的行为。不使用 `ALL` 时，`AFTER` 仅会求值到起始 chunk 为止；后续 chunk 仅求值 `UNTIL`。位于起始位置之前的结束匹配仍然不起作用。

**示例：**

从 `number >= 3` 为 true 的第一行开始的前 3 行：

```sql theme={null}
SELECT number FROM numbers(10) ORDER BY number LIMIT 3 AFTER number >= 3;
```

```response theme={null}
┌─number─┐
│      3 │
│      4 │
│      5 │
└────────┘
```

从 `number >= 2` 的第一行起，至 (不包括) `number >= 6` 的第一行：

```sql theme={null}
SELECT number FROM numbers(10) ORDER BY number LIMIT 10 AFTER number >= 2 UNTIL number >= 6;
```

```response theme={null}
┌─number─┐
│      2 │
│      3 │
│      4 │
│      5 │
└────────┘
```

未指定 `n` 时，将返回从匹配 `AFTER` 的位置到 stream 末尾 (或 `UNTIL` 之前) 的所有行：

```sql theme={null}
SELECT number FROM numbers(10) ORDER BY number LIMIT AFTER number >= 7;
```

```response theme={null}
┌─number─┐
│      7 │
│      8 │
│      9 │
└────────┘
```

未指定 `n` 但使用 `UNTIL` 时，范围从第一个 `AFTER` 匹配项开始，到位于该匹配项处或其之后的第一个 `UNTIL` 匹配项为止：

```sql theme={null}
SELECT number FROM numbers(10) ORDER BY number LIMIT AFTER number >= 2 UNTIL number >= 6;
```

```response theme={null}
┌─number─┐
│      2 │
│      3 │
│      4 │
│      5 │
└────────┘
```

在起始位置之前出现的 `UNTIL` 匹配会被忽略；此处 `number = 1` 不起作用，范围在 `number = 6` 之前结束：

```sql theme={null}
SELECT number FROM numbers(10) ORDER BY number LIMIT AFTER number = 3 UNTIL number IN (1, 6);
```

```response theme={null}
┌─number─┐
│      3 │
│      4 │
│      5 │
└────────┘
```

在每个匹配行后输出 2 行，且不重复输出重叠部分：

```sql theme={null}
SELECT number FROM numbers(10) ORDER BY number LIMIT 2 AFTER number IN (2, 3, 6) ALL;
```

```response theme={null}
┌─number─┐
│      2 │
│      3 │
│      4 │
│      6 │
│      7 │
└────────┘
```

同时使用 `ALL` 和 `UNTIL` 时，每个已开启的范围会在达到 `n` 行或遇到下一个 `UNTIL` 匹配时结束，以先到者为准；此处在 6 处开启的范围被 `number = 7` 截断：

```sql theme={null}
SELECT number FROM numbers(10) ORDER BY number LIMIT 2 AFTER number IN (2, 6) ALL UNTIL number = 7;
```

```response theme={null}
┌─number─┐
│      2 │
│      3 │
│      6 │
└────────┘
```

不使用 `n` 时，`UNTIL` 匹配会关闭当前范围，随后的 `AFTER` 匹配会开启一个新范围；若之后不再出现 `UNTIL` 匹配，该范围将延伸至末尾：

```sql theme={null}
SELECT number FROM numbers(10) ORDER BY number LIMIT AFTER number IN (2, 6) ALL UNTIL number = 4;
```

```response theme={null}
┌─number─┐
│      2 │
│      3 │
│      6 │
│      7 │
│      8 │
│      9 │
└────────┘
```

不使用 `n` 和 `UNTIL` 时，每个已开启的范围都会延伸至 stream 末尾，因此 `AFTER start_expr ALL` 返回的行与 `AFTER start_expr` 相同。

<Note>
  * `WITH TIES`、小数或负数 `LIMIT`/`OFFSET` 以及 `OFFSET` 不支持与 `AFTER`/`UNTIL` 结合使用。
  * 使用 `AFTER`/`UNTIL` 时，会禁用预先 `LIMIT` 下推。
  * 只有在 `AFTER` 和 `UNTIL` 后跟边界表达式时，它们才会被识别为关键字。因此，名为 `after` 或 `until` 的标识符仍可用作行数 (`LIMIT after`、`LIMIT after BY x`) 。当两种解释均可行时，关键字优先：`LIMIT after(2)` 表示范围 `LIMIT AFTER (2)`；若要调用名为 `after` 的函数，请写作 `LIMIT (after(2))`。
</Note>

单独使用 `UNTIL` 会返回从 stream 开头到条件首次为 true 的行之前的所有行：

```sql theme={null}
SELECT number FROM numbers(10) ORDER BY number LIMIT UNTIL number >= 3;
```

```response theme={null}
┌─number─┐
│      0 │
│      1 │
│      2 │
└────────┘
```

使用 `n` 时，`UNTIL` 单独使用会从 stream 开头最多返回 `n` 行，但仍会在第一次匹配处停止：

```sql theme={null}
SELECT number FROM numbers(10) ORDER BY number LIMIT 2 UNTIL number >= 3;
```

```response theme={null}
┌─number─┐
│      0 │
│      1 │
└────────┘
```

范围可位于 [`LIMIT BY`](/zh/reference/statements/select/limit-by) 之后，并应用于 `LIMIT BY` 保留的行：

```sql theme={null}
SELECT number % 4 AS k, number FROM numbers(12) ORDER BY k, number LIMIT 2 BY k LIMIT 3 AFTER k >= 1;
```

```response theme={null}
┌─k─┬─number─┐
│ 1 │      1 │
│ 1 │      5 │
│ 2 │      2 │
└───┴────────┘
```

## 注意事项

\*\*非确定性结果：\*\*如果没有 [`ORDER BY`](/zh/reference/statements/select/order-by) 子句，返回的行可能是任意的，并且在多次执行查询时可能会有所不同。

\*\*服务器端限制：\*\*返回的行数也可能受到 [limit](/zh/reference/settings/session-settings/other#limit) 设置的影响。

## 另请参阅

* [LIMIT BY](/zh/reference/statements/select/limit-by) — 限制每组值中的行数，适用于获取每个类别下前 N 个结果。
