使用 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
预期结果
我的预期结果如下:
- limit=1,offset=0 -> return isbn 最低的第一个列表 returned
- limit=1,offset=1 -> return 大小为一的列表,第二低的 isbn 为 returned
- limit=1,offset=2 -> return 第一大小的列表,第三低的 isbn 是 returned
- limit=1,offset=3 -> return 大小为一的列表,第四低的 isbn 为 returned
- limit=1,offset=x (x>=4) -> return 空列表
- limit=2,offset=0 -> return 大小为 2 的列表,其中两个最低的 isbn 为 returned
- limit=2,offset=1 -> return 大小为 second/third 最低 isbn 的列表 returned
- limit=2,offset=2 -> return 大小为 third/fourth isbn 的列表 returned
- limit=2,offset=3 -> return 大小为一的列表,第四低的 isbn 为 returned
- limit=2,offset=x (x>=4) -> return空列表
- limit=3,offset=0 -> return 三个最低 isbn 的大小列表
- limit=3,offset=1 -> return 三号列表,second/third/第四低 isbn 为 returned
- limit=3,offset=2 -> return 大小为 third/fourth 最低 isbn 的列表 returned
- limit=3,offset=3 -> return 第一大小的列表,第四低的 isbn 是 returned
- limit=3,offset=x (x>=4) -> return空列表
- limit=x,offset=0 (x>=4) -> return 大小为 4 的列表,其中包含所有 isbn
- limit=x,offset=1 (x>=4) -> return 三号列表,second/third/第四低 isbn 为 returned
- limit=x,offset=2 (x>=4) -> return 大小为 third/fourth 最低 isbn 的列表 returned
- limit=x,offset=3 (x>=4) -> return 第一大小的列表,第四低的 isbn 是 returned
实际结果
- limit=1,offset=0 -> 空列表returned (sql 运行 SELECT ISBN,AUTHOR_FIRST_NAME ,AUTHOR_LAST_NAME,TITLE,NUMBER_OF_POINTS,IS_VERIFIED,READING_LEVEL,CREATED_TEACHER_ID 来自 ISBN ASC LIMIT 1, 0[=86 的评估顺序=]
- limit=1,offset=1 -> 大小一列表 (sql 运行 SELECT ISBN,AUTHOR_FIRST_NAME,AUTHOR_LAST_NAME,TITLE,NUMBER_OF_POINTS,IS_VERIFIED,READING_LEVEL,CREATED_TEACHER_ID 来自 ISBN ASC LIMIT 1, 1)
的评估顺序
- limit=1,offset=2 -> 二号列表
- limit=1,offset=3 ->
- limit=1,offset=x (x>=4) ->
- limit=2,offset=0 ->
- limit=2,offset=1 ->
- limit=2,offset=2 ->
- limit=2,offset=3 ->
- limit=2,offset=x (x>=4) ->
- limit=3,offset=0 -> 空列表 (sql 运行 * SELECT ISBN,AUTHOR_FIRST_NAME,AUTHOR_LAST_NAME,TITLE,NUMBER_OF_POINTS,IS_VERIFIED,READING_LEVEL,CREATED_TEACHER_ID 来自 ISBN ASC LIMIT 3, 0*)
的评估顺序
- limit=3,offset=1 ->
- limit=3,offset=2 ->
- limit=3,offset=3 ->
- limit=3,offset=x (x>=4) ->
- limit=x,offset=0 (x>=4) ->
- limit=x,offset=1 (x>=4) ->
- limit=x,offset=2 (x>=4) ->
- limit=x,offset=3 (x>=4) ->
问题:
- 我创建 sql 是否正确?
- 如果我是,这是 mysql/how 的问题吗?我会补救这个问题以产生预期的结果吗?
- 如果不是,我该如何更正我的查询以产生预期的结果?是不是翻我的limit/offset这么简单?
- 欢迎就如何实现此功能提出任何一般性意见。
谢谢,
康纳
题目准备满分,
如果我看到问题并理解正确,问题出在您下的订单 limit
和 offset
有两种方法,
或者您明确提及 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 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
所以查询可以是
SELECT * FROM Table LIMIT 0, 1
或
SELECT * FROM Table LIMIT 1 OFFSET 0
我正在实现一个 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
预期结果 我的预期结果如下:
- limit=1,offset=0 -> return isbn 最低的第一个列表 returned
- limit=1,offset=1 -> return 大小为一的列表,第二低的 isbn 为 returned
- limit=1,offset=2 -> return 第一大小的列表,第三低的 isbn 是 returned
- limit=1,offset=3 -> return 大小为一的列表,第四低的 isbn 为 returned
- limit=1,offset=x (x>=4) -> return 空列表
- limit=2,offset=0 -> return 大小为 2 的列表,其中两个最低的 isbn 为 returned
- limit=2,offset=1 -> return 大小为 second/third 最低 isbn 的列表 returned
- limit=2,offset=2 -> return 大小为 third/fourth isbn 的列表 returned
- limit=2,offset=3 -> return 大小为一的列表,第四低的 isbn 为 returned
- limit=2,offset=x (x>=4) -> return空列表
- limit=3,offset=0 -> return 三个最低 isbn 的大小列表
- limit=3,offset=1 -> return 三号列表,second/third/第四低 isbn 为 returned
- limit=3,offset=2 -> return 大小为 third/fourth 最低 isbn 的列表 returned
- limit=3,offset=3 -> return 第一大小的列表,第四低的 isbn 是 returned
- limit=3,offset=x (x>=4) -> return空列表
- limit=x,offset=0 (x>=4) -> return 大小为 4 的列表,其中包含所有 isbn
- limit=x,offset=1 (x>=4) -> return 三号列表,second/third/第四低 isbn 为 returned
- limit=x,offset=2 (x>=4) -> return 大小为 third/fourth 最低 isbn 的列表 returned
- limit=x,offset=3 (x>=4) -> return 第一大小的列表,第四低的 isbn 是 returned
实际结果
- limit=1,offset=0 -> 空列表returned (sql 运行 SELECT ISBN,AUTHOR_FIRST_NAME ,AUTHOR_LAST_NAME,TITLE,NUMBER_OF_POINTS,IS_VERIFIED,READING_LEVEL,CREATED_TEACHER_ID 来自 ISBN ASC LIMIT 1, 0[=86 的评估顺序=]
- limit=1,offset=1 -> 大小一列表 (sql 运行 SELECT ISBN,AUTHOR_FIRST_NAME,AUTHOR_LAST_NAME,TITLE,NUMBER_OF_POINTS,IS_VERIFIED,READING_LEVEL,CREATED_TEACHER_ID 来自 ISBN ASC LIMIT 1, 1) 的评估顺序
- limit=1,offset=2 -> 二号列表
- limit=1,offset=3 ->
- limit=1,offset=x (x>=4) ->
- limit=2,offset=0 ->
- limit=2,offset=1 ->
- limit=2,offset=2 ->
- limit=2,offset=3 ->
- limit=2,offset=x (x>=4) ->
- limit=3,offset=0 -> 空列表 (sql 运行 * SELECT ISBN,AUTHOR_FIRST_NAME,AUTHOR_LAST_NAME,TITLE,NUMBER_OF_POINTS,IS_VERIFIED,READING_LEVEL,CREATED_TEACHER_ID 来自 ISBN ASC LIMIT 3, 0*) 的评估顺序
- limit=3,offset=1 ->
- limit=3,offset=2 ->
- limit=3,offset=3 ->
- limit=3,offset=x (x>=4) ->
- limit=x,offset=0 (x>=4) ->
- limit=x,offset=1 (x>=4) ->
- limit=x,offset=2 (x>=4) ->
- limit=x,offset=3 (x>=4) ->
问题:
- 我创建 sql 是否正确?
- 如果我是,这是 mysql/how 的问题吗?我会补救这个问题以产生预期的结果吗?
- 如果不是,我该如何更正我的查询以产生预期的结果?是不是翻我的limit/offset这么简单?
- 欢迎就如何实现此功能提出任何一般性意见。
谢谢, 康纳
题目准备满分,
如果我看到问题并理解正确,问题出在您下的订单 limit
和 offset
有两种方法,
或者您明确提及 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 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
所以查询可以是
SELECT * FROM Table LIMIT 0, 1
或
SELECT * FROM Table LIMIT 1 OFFSET 0