使用 mysql 实现分页(限制和偏移量)

Implementing pagination with mysql (limit and offset)

我正在实现一个 RESTful api,它有一个需要支持分页的 GET 端点。为此,我实施了标准限制和偏移量查询参数。当我到达 (mysql) 数据库时,我需要以有序、一致的方式获取数据。我试图在我的查询中使用 'order by' 和 'limit x, y' 组合,但预期的结果没有被 returned.

DDL/DML

这是用于创建 tables/indexes (ddl) 和插入数据 (dml) 的(唯一)脚本:https://gitlab.com/connorbutch/reading-comprehension/-/blob/9-list-all-assessments/reading-comprehension-server-quarkus-impl/src/main/resources/db/migration/V1.0.0__CreateAssessment.sql。文件内容也如下:

CREATE TABLE ASSESSMENT(
  ISBN BIGINT NOT NULL
, AUTHOR_FIRST_NAME VARCHAR(32)
, AUTHOR_LAST_NAME VARCHAR(32)
, TITLE VARCHAR(128) NOT NULL
, NUMBER_OF_POINTS FLOAT NOT NULL
, IS_VERIFIED BOOLEAN DEFAULT FALSE
, READING_LEVEL FLOAT NOT NULL
, CREATED_TEACHER_ID MEDIUMINT
) ENGINE=INNODB DEFAULT CHARSET=latin1;


CREATE UNIQUE INDEX ASSESSMENT_X01 ON ASSESSMENT(
    ISBN
);

ALTER TABLE ASSESSMENT
ADD CONSTRAINT ASSESSMENT_PK PRIMARY KEY(
    ISBN
);

CREATE INDEX ASSESSMENT_X02 ON ASSESSMENT(
    TITLE
);

CREATE INDEX ASSESSMENT_X03 ON ASSESSMENT(
    CREATED_TEACHER_ID
);

INSERT INTO ASSESSMENT(ISBN, AUTHOR_FIRST_NAME, AUTHOR_LAST_NAME, TITLE, NUMBER_OF_POINTS, IS_VERIFIED, READING_LEVEL, CREATED_TEACHER_ID)
            VALUES(9781976530739, 'Herman', 'Melleville', 'Moby Dick', 65, FALSE, 10.8, 1);

INSERT INTO rc.ASSESSMENT(ISBN, AUTHOR_FIRST_NAME, AUTHOR_LAST_NAME, TITLE, NUMBER_OF_POINTS, IS_VERIFIED, READING_LEVEL, CREATED_TEACHER_ID)
            VALUES(0486282112, 'Mary', 'Shelley', 'Frankenstein', 22, FALSE, 12.0, 1);

INSERT INTO rc.ASSESSMENT(ISBN, AUTHOR_FIRST_NAME, AUTHOR_LAST_NAME, TITLE, NUMBER_OF_POINTS, IS_VERIFIED, READING_LEVEL, CREATED_TEACHER_ID)
            VALUES(1503275922, 'Joseph', 'Conrad', 'Heart of Darkness', 36, FALSE, 12.5, 1);

INSERT INTO rc.ASSESSMENT(ISBN, AUTHOR_FIRST_NAME, AUTHOR_LAST_NAME, TITLE, NUMBER_OF_POINTS, IS_VERIFIED, READING_LEVEL, CREATED_TEACHER_ID)
            VALUES(0679732764, 'Ralph', 'Ellison', 'Invisible Man', 30, FALSE, 9.8, 1);

SQL查询 查询 运行 从评估 table 中检索条目可以在以下位置找到:https://gitlab.com/connorbutch/reading-comprehension/-/blob/9-list-all-assessments/reading-comprehension-server-quarkus-impl/src/main/resources/sql.properties。为方便起见,我还将其包含在下面

GET_ALL_ASSESSMENTS=SELECT ISBN,AUTHOR_FIRST_NAME,AUTHOR_LAST_NAME,TITLE,NUMBER_OF_POINTS,IS_VERIFIED,READING_LEVEL,CREATED_TEACHER_ID FROM ASSESSMENT ORDER BY ISBN ASC
GET_ASSESSMENT_LIMIT_OFFSET=SELECT ISBN,AUTHOR_FIRST_NAME,AUTHOR_LAST_NAME,TITLE,NUMBER_OF_POINTS,IS_VERIFIED,READING_LEVEL,CREATED_TEACHER_ID FROM ASSESSMENT ORDER BY ISBN ASC LIMIT :LIMIT, :OFFSET
GET_ASSESSMENT_COUNT=SELECT COUNT(1) FROM ASSESSMENT

预期结果 我的预期结果如下:

实际结果

问题:

  1. 我创建 sql 是否正确?
  2. 如果我是,这是 mysql/how 的问题吗?我会补救这个问题以产生预期的结果吗?
  3. 如果不是,我该如何更正我的查询以产生预期的结果?是不是翻我的limit/offset这么简单?
  4. 欢迎就如何实现此功能提出任何一般性意见。

谢谢, 康纳

题目准备满分,

如果我看到问题并理解正确,问题出在您下的订单 limitoffset

有两种方法,

或者您明确提及 limitoffset 作为,

SELECT ISBN,AUTHOR_FIRST_NAME,AUTHOR_LAST_NAME,TITLE,NUMBER_OF_POINTS,IS_VERIFIED,READING_LEVEL,CREATED_TEACHER_ID 
FROM ASSESSMENT 
ORDER BY ISBN ASC LIMIT 1 OFFSET 0;

如果您不想明确提及 offset 这个词,我们需要先传递 offset 值,然后再传递 limit 值作为

SELECT ISBN,AUTHOR_FIRST_NAME,AUTHOR_LAST_NAME,TITLE,NUMBER_OF_POINTS,IS_VERIFIED,READING_LEVEL,CREATED_TEACHER_ID 
FROM ASSESSMENT 
ORDER BY ISBN ASC LIMIT 0,1;

P.S。我没有像您提到的那样测试每个案例,但我想如果我的理解正确,您现在就知道该怎么做了。

你把它倒过来了LIMIT *OFFSET*, *ROW_COUNT* 或者你可以使用 OFFSET

MySQL Documentation

所以查询可以是

SELECT * FROM Table LIMIT 0, 1

SELECT * FROM Table LIMIT 1 OFFSET 0

MySQL Documentation