适用版本: Dev (3.21) | 最新版 (3.20) | 3.19 | 3.18 | 3.17 | 3.16 | 3.15 | 3.14 | 3.13 | 3.12 | 3.11

LIMIT .. OFFSET子句

适用于 ✅ 开源版   ✅ 专业版   ✅ 企业版

虽然此子句对于任何执行分页的应用程序或者只是将结果集限制为合理大小的应用程序都非常有用,但它直到 SQL:2008 才被标准化。因此,关于此限制子句,各种 SQL 方言中存在各种可能的实现。 jOOQ 选择实现 MySQL、H2、HSQLDB、Postgres 和 SQLite 理解和支持的 LIMIT .. OFFSET 子句。 以下是如何使用 jOOQ 应用限制的示例

create.select().from(BOOK).orderBy(BOOK.ID).limit(1).offset(2).fetch();

这将限制结果为 1 本书,跳过前 2 本书(偏移量为 2)。 limit() 在所有方言中都支持,offset() 除了 Sybase ASE 之外的所有方言都支持,Sybase ASE 没有合理的模拟方法。 这是 jOOQ 如何在各种 SQL 方言中轻松模拟上述查询,并支持原生 OFFSET 分页

-- MySQL, H2, HSQLDB, and SQLite
SELECT * FROM BOOK ORDER BY ID LIMIT 1 OFFSET 2

-- Derby, SQL Server 2012, Oracle 12c, PostgreSQL, the SQL:2008 standard
SELECT * FROM BOOK ORDER BY ID OFFSET 2 ROWS FETCH NEXT 1 ROWS ONLY

-- Informix has SKIP .. FIRST support
SELECT SKIP 2 FIRST 1 * FROM BOOK ORDER BY ID

-- Ingres (almost the SQL:2008 standard)
SELECT * FROM BOOK ORDER BY ID OFFSET 2 FETCH FIRST 1 ROWS ONLY

-- Firebird
SELECT * FROM BOOK ORDER BY ID ROWS 2 TO 3

-- Sybase SQL Anywhere
SELECT TOP 1 START AT 3 * FROM BOOK ORDER BY ID

-- DB2 (almost the SQL:2008 standard, without OFFSET)
SELECT * FROM BOOK ORDER BY ID FETCH FIRST 1 ROWS ONLY

-- Sybase ASE, SQL Server 2008 (without OFFSET)
SELECT TOP 1 * FROM BOOK ORDER BY ID

在那些没有 OFFSET 分页原生语法的数据库中,事情变得更加棘手(实际查询可能会有所不同)

-- DB2 (with OFFSET), SQL Server 2008 (with OFFSET)
SELECT * FROM (
  SELECT BOOK.*,
    ROW_NUMBER() OVER (ORDER BY ID ASC) AS RN
  FROM BOOK
) AS X
WHERE RN > 2
AND RN <= 3

-- DB2 (with OFFSET), SQL Server 2008 (with OFFSET)
SELECT * FROM (
  SELECT DISTINCT BOOK.ID, BOOK.TITLE,
    DENSE_RANK() OVER (ORDER BY ID ASC, TITLE ASC) AS RN
  FROM BOOK
) AS X
WHERE RN > 2
AND RN <= 3

-- Oracle 11g and less
SELECT *
FROM (
  SELECT b.*, ROWNUM RN
  FROM (
    SELECT *
    FROM BOOK
    ORDER BY ID ASC
  ) b
  WHERE ROWNUM <= 3
)
WHERE RN > 2

正如您所看到的,jOOQ 将为您处理子查询中令人难以置信的痛苦的 ROW_NUMBER() OVER() (或 Oracle 的 ROWNUM) 过滤,您只需在任何方言中编写 limit(1).offset(2) 即可。

SQL Server 的 ORDER BY、TOP 和子查询

如以上示例所示,根据 SQL 方言的不同,编写正确的 SQL 可能会非常棘手。 例如,对于 SQL Server,除非您还具有 TOP 子句,否则不能在子查询中具有 ORDER BY 子句。 jOOQ 为您呈现 TOP 100 PERCENT 子句这一事实说明了这一点。 同样的情况也适用于 ROW_NUMBER() OVER() 需要 ORDER BY 窗口子句,即使您没有为 jOOQ 查询提供一个。 默认情况下,jOOQ 会按投影的第一列添加排序。

键集分页

请注意,LIMIT 子句也可以与 SEEK 子句 一起使用以进行键集分页。

反馈

您对此页面有任何反馈吗? 我们很乐意听取您的意见!

The jOOQ Logo