LIMIT 子句用于从查询结果中选取指定数量的记录,它通常用于实现分页功能,也就是我们常说的“上一页/下一页”浏览数据。

sql教程 limit
(图片来源网络,侵删)

LIMIT 的基本语法

LIMIT 子句通常放在 SELECT 语句的末尾。

基本语法(只限制数量)

SELECT column1, column2, ...
FROM table_name
LIMIT number_of_rows;
  • number_of_rows: 你希望返回的记录数量。

示例: 假设我们有一个 products 表,我们只想获取前 5 个产品。

SELECT * FROM products LIMIT 5;

这条语句会返回 products 表中按默认顺序排列的前 5 行数据。


LIMIT 的进阶语法(带偏移量)

如果你想从某一特定位置开始获取数据,而不是从第一行开始,就需要使用带偏移量的 LIMIT 语法。

sql教程 limit
(图片来源网络,侵删)

语法(限制数量并指定偏移量)

SELECT column1, column2, ...
FROM table_name
LIMIT number_of_rows OFFSET offset_value;
  • number_of_rows: 你希望返回的记录数量。
  • offset_value: 跳过前面的多少条记录后再开始取数据。

示例: 假设我们想获取第 6 到第 10 个产品。

  • offset_value 应该是 5 (跳过前 5 条)。
  • number_of_rows 应该是 5 (取 5 条)。
SELECT * FROM products LIMIT 5 OFFSET 5;

LIMIT 的替代语法(MySQL 和 PostgreSQL)

在 MySQL 和 PostgreSQL 中,LIMIT 子句支持一种更简洁的写法,使用逗号 来分隔偏移量和数量。

SELECT column1, column2, ...
FROM table_name
LIMIT offset_value, number_of_rows;

注意: 这种写法在某些数据库(如 SQL Server)中会报错,因为它会被解析为 LIMIT offset_value

示例: 同样,获取第 6 到第 10 个产品。

-- MySQL / PostgreSQL 语法
SELECT * FROM products LIMIT 5, 5;

这个语句的含义是:跳过前 5 条,然后取 5 条,结果与上面的 LIMIT 5 OFFSET 5 完全相同。


LIMIT 在不同数据库中的实现

虽然 LIMIT 非常流行,但并非所有数据库都使用它,了解其他数据库的实现方式很重要,因为 SQL 虽然有标准,但不同数据库厂商的实现常有差异。

数据库 语法 示例 (获取第 6-10 条)
MySQL LIMIT offset, countLIMIT count OFFSET offset LIMIT 5, 5LIMIT 5 OFFSET 5
PostgreSQL LIMIT count OFFSET offset LIMIT 5 OFFSET 5
SQLite LIMIT offset, countLIMIT count OFFSET offset LIMIT 5, 5LIMIT 5 OFFSET 5
SQL Server 使用 OFFSET ... FETCH NEXT ... OFFSET 5 ROWS FETCH NEXT 5 ROWS ONLY
Oracle 使用 FETCH ... OFFSET ... (Oracle 12c 及以上版本) OFFSET 5 ROWS FETCH NEXT 5 ROWS ONLY
DB2 使用 FETCH ... OFFSET ... OFFSET 5 ROWS FETCH NEXT 5 ROWS ONLY

实战应用:分页

LIMIT 最常见的应用场景就是分页,假设我们每页显示 10 条数据。

  • 第 1 页:

    • 跳过 0 条,取 10 条。
      SELECT * FROM products ORDER BY id LIMIT 10 OFFSET 0;
  • 第 2 页:

    • 跳过 10 条,取 10 条。
      SELECT * FROM products ORDER BY id LIMIT 10 OFFSET 10;
  • 第 N 页:

    • 跳过 (N-1) * 10 条,取 10 条。
      -- 假设 page_number 是变量,值为 3
      SELECT * FROM products ORDER BY id LIMIT 10 OFFSET (3 - 1) * 10;
      -- 即: SELECT * FROM products ORDER BY id LIMIT 10 OFFSET 20;

重要提示: 在进行分页查询时,一定要使用 ORDER BY 子句!否则,数据的顺序是不确定的,你可能会在每一页看到重复的数据或遗漏某些数据。


注意事项和最佳实践

  1. 性能问题: 对于深度分页(跳过 100,000 条记录来获取第 10,001 页),OFFSET 的性能可能会很差,数据库需要扫描并丢弃前 100,000 条记录,这是一个昂贵的操作。

    • 解决方案: 对于超大数据集,可以考虑基于“游标”(Cursor)的分页方法,即使用 WHERE 子句记录上一页最后一条记录的 ID,然后从该 ID 之后开始查询。WHERE id > last_seen_id ORDER BY id LIMIT 10
  2. 使用 ORDER BY 再次强调,只要涉及到分页或任何需要特定顺序的结果,都应该使用 ORDER BY 来确保结果的确定性。

  3. 数据库兼容性: 在编写跨数据库的 SQL 时,要特别注意 LIMIT 语法的差异,如果你的应用需要支持多种数据库,可能需要根据数据库类型动态生成 SQL 语句,或者使用对象关系映射工具(如 Hibernate, SQLAlchemy)来处理这些差异。

功能 MySQL / PostgreSQL / SQLite 语法 SQL Server / Oracle / DB2 语法
取前 N 条 SELECT ... LIMIT N SELECT ... TOP N (SQL Server) 或 SELECT ... FETCH FIRST N ROWS ONLY (Oracle/DB2)
从 M 条开始,取 N 条 SELECT ... LIMIT N OFFSET M SELECT ... OFFSET M ROWS FETCH NEXT N ROWS ONLY

希望这个详细的教程能帮助你完全掌握 SQL 的 LIMIT 子句!