Skip to content

SQL Select Top

当查询数据时,经常需要只检索特定数量的行,或者根据某个顺序检索前 N 行。这对于处理大型表时的性能以及分页等功能至关重要。

不同的数据库系统使用不同的子句来实现此目的:LIMIT(MySQL、PostgreSQL、SQLite)、FETCH FIRST N ROWS ONLY(SQL 标准,Oracle 12c+)和 TOP N(SQL Server、MS Access)。

使用这些子句可以显著提高查询性能,尤其是在包含成千上万或数百万条记录的表中,通过减少传输和处理的数据量来实现。

LIMIT 子句限制查询返回的行数。

SELECT column_name(s) FROM table_name WHERE condition ORDER BY column_name(s) LIMIT number;

TOP 子句用于指定要返回的记录数量或百分比。

SELECT TOP number|PERCENT column_name(s) FROM table_name WHERE condition ORDER BY column_name(s);

注意:在使用 TOP、LIMIT 或 FETCH 时,ORDER BY 通常是必不可少的,以确保获取到有意义的数据子集(例如,得分最高的 10 条记录)。如果没有 ORDER BY,则无法保证返回的行具有任何特定的顺序。

Oracle (12c 及更高版本) / SQL 标准: FETCH FIRST 子句

Section titled “Oracle (12c 及更高版本) / SQL 标准: FETCH FIRST 子句”

FETCH FIRST N ROWS ONLY 子句是标准 SQL 中限制行数的方法。Oracle 12c 及更高版本支持此语法。

SELECT column_name(s) FROM table_name WHERE condition ORDER BY column_name(s) FETCH FIRST number ROWS ONLY;

Oracle (12c 之前): ROWNUM (经典方法)

Section titled “Oracle (12c 之前): ROWNUM (经典方法)”

对于较旧的 Oracle 版本,通常在子查询中使用 ROWNUM,因为如果在同一查询级别使用,ROWNUM 会在 ORDER BY 之前应用。

SELECT column_name(s) FROM ( SELECT column_name(s), ROWNUM as rn FROM table_name WHERE condition ORDER BY column_name(s) ) WHERE rn <= number;

对于本节中的示例,假设有一个 Products 表,包含 ProductID、ProductName、SupplierID、CategoryID、UnitPrice 和 UnitsInStock 等列。

示例:获取前 5 个产品 (MySQL/PostgreSQL/SQLite)

Section titled “示例:获取前 5 个产品 (MySQL/PostgreSQL/SQLite)”

此查询检索前 5 个产品。如果未指定排序,则顺序可能是任意的。

SELECT ProductName, UnitPrice
FROM Products
LIMIT 5;

示例:获取最贵的 3 个产品 (MySQL/PostgreSQL/SQLite)

Section titled “示例:获取最贵的 3 个产品 (MySQL/PostgreSQL/SQLite)”
SELECT ProductName, UnitPrice
FROM Products
ORDER BY UnitPrice DESC
LIMIT 3;

示例:获取前 5 个产品 (SQL Server)

Section titled “示例:获取前 5 个产品 (SQL Server)”
SELECT TOP 5 ProductName, UnitPrice
FROM Products;

示例:获取最贵的 3 个产品 (SQL Server)

Section titled “示例:获取最贵的 3 个产品 (SQL Server)”
SELECT TOP 3 ProductName, UnitPrice
FROM Products
ORDER BY UnitPrice DESC;

示例:按价格获取前 10% 的产品 (SQL Server)

Section titled “示例:按价格获取前 10% 的产品 (SQL Server)”
SELECT TOP 10 PERCENT ProductName, UnitPrice
FROM Products
ORDER BY UnitPrice DESC;

示例:获取最贵的 3 个产品 (Oracle 12c+ / SQL 标准)

Section titled “示例:获取最贵的 3 个产品 (Oracle 12c+ / SQL 标准)”
SELECT ProductName, UnitPrice
FROM Products
ORDER BY UnitPrice DESC
FETCH FIRST 3 ROWS ONLY;

示例:获取最贵的 3 个产品 (Oracle pre-12c)

Section titled “示例:获取最贵的 3 个产品 (Oracle pre-12c)”
SELECT ProductName, UnitPrice
FROM (
SELECT ProductName, UnitPrice
FROM Products
ORDER BY UnitPrice DESC
)
WHERE ROWNUM <= 3;

限制子句是应用程序中实现分页的基础,其中数据以块(页面)形式显示,而不是一次性显示。例如,要获取每页 10 个产品的第二页(即跳过前 10 条记录,再取 10 条):

SELECT ProductName, UnitPrice
FROM Products
ORDER BY ProductID
LIMIT 10 OFFSET 10; -- Skip first 10, take next 10

SQL Server 语法 (使用 OFFSET/FETCH, SQL Server 2012+):

Section titled “SQL Server 语法 (使用 OFFSET/FETCH, SQL Server 2012+):”
SELECT ProductName, UnitPrice
FROM Products
ORDER BY ProductID
OFFSET 10 ROWS
FETCH NEXT 10 ROWS ONLY;
SELECT ProductName, UnitPrice
FROM Products
ORDER BY ProductID
OFFSET 10 ROWS
FETCH NEXT 10 ROWS ONLY;

有关不同 SQL 数据库中分页策略的更多信息,您可以查阅其各自的文档或搜索“SQL 分页技术”。