[英]android sqlite query with offset doesn't return desired rows
I'm using the following code to get a list of notifications (total rows are 21) : 我正在使用以下代码获取通知列表(总行数为21) :
List<Notification> list = new ArrayList<Notification>();
Cursor c = _db.query(TABLE_NAME, COL_ALL, null, null, null, null, order, get_limitStr(offset));
if(c != null && c.moveToFirst())
{
while(!c.isAfterLast())
{
Notification model = cursorToModel(c);
if(model != null)
{
list.add(model);
}
c.moveToNext();
}
c.close();
}
and the generated query for offset = 0 is 并且生成的offset = 0的查询是
SELECT Id, Token, Title, Read, Message, Image, CreateDate, CreateDateFA FROM Notifications ORDER BY CreateDate DESC LIMIT 20,0
and it works as it's supposed to and returns 20 rows, when I increase offset by 1 (offset = 1) it returns only 1 row which is correct but the problem is when the offset is bigger than 1 then the query will be 并且它按预期工作并返回20行,当我将偏移量增加1(偏移= 1)时,它只返回1行,这是正确的,但问题是当偏移量大于1时,查询将是
SELECT Id, Token, Title, Read, Message, Image, CreateDate, CreateDateFA FROM Notifications ORDER BY CreateDate DESC LIMIT 20,2
and I thought it supposed to skip 20 * 2 rows and then starts taking rows from there, which either my thought or my query is wrong. 我认为它应该跳过20 * 2行,然后开始从那里开始行,这是我的想法或我的查询是错误的。 What am I doing wrong here? 我在这做错了什么? Thanks 谢谢
LIMIT 20,2
and I thought it supposed to skip 20 * 2 rows and then starts taking rows from there, which either my thought or my query is wrong. 我认为它应该跳过20 * 2行,然后开始从那里开始行,这是我的想法或我的查询是错误的。
LIMIT 20,2
skips first 20 rows and returns at most 2 remaining rows. LIMIT 20,2
跳过前20行并返回最多2个剩余行。 It's the same as LIMIT 2 OFFSET 20
. 它与LIMIT 2 OFFSET 20
相同。
Even the documentation says it's counter-intuitive: 甚至文档都说这是违反直觉的:
Instead of a separate OFFSET clause, the LIMIT clause may specify two scalar expressions separated by a comma. LIMIT子句可以指定由逗号分隔的两个标量表达式,而不是单独的OFFSET子句。 In this case, the first expression is used as the OFFSET expression and the second as the LIMIT expression. 在这种情况下,第一个表达式用作OFFSET表达式,第二个表达式用作LIMIT表达式。 This is counter-intuitive, as when using the OFFSET clause the second of the two expressions is the OFFSET and the first the LIMIT. 这是违反直觉的,因为当使用OFFSET子句时,两个表达式中的第二个是OFFSET,第一个是LIMIT。 This reversal of the offset and limit is intentional - it maximizes compatibility with other SQL database systems. 这种偏移和限制的逆转是有意的 - 它最大化了与其他SQL数据库系统的兼容性。 However, to avoid confusion, programmers are strongly encouraged to use the form of the LIMIT clause that uses the "OFFSET" keyword and avoid using a LIMIT clause with a comma-separated offset. 但是,为了避免混淆,强烈建议程序员使用LIMIT子句的形式使用“OFFSET”关键字,并避免使用带逗号分隔偏移量的LIMIT子句。
If you want to achieve sort of result paging with page size of 20, use something like OFFSET k*20 LIMIT 20
where k
is your zero-based page number. 如果要实现页面大小为20的结果分页,请使用类似OFFSET k*20 LIMIT 20
,其中k
是从零开始的页码。
You can use offset within Cursor
as "offset,limit" value: 您可以在Cursor
使用offset作为“offset,limit”值:
Cursor cursor = db.query(
TABLE_NAME,
new String[]{COLUMN_NAME_1, COLUMN_NAME_2, COLUMN_NAME_3},
null,
null,
null,
null,
null,
"6,1000");
In this example I selected all rows(I suppose no more than 1000) starting from the 7th one. 在这个例子中,我从第7个开始选择了所有行(我想不超过1000行)。 Here 6 is your offset and 1000 the limit. 这里6是你的偏移,1000是限制。
Here need to understand both LIMIT <offset>, <count>
& LIMIT <count> OFFSET <offset>
are equivalent. 这里需要理解LIMIT <offset>, <count>
和LIMIT <count> OFFSET <offset>
是等价的。
An example: 一个例子:
A) We have an table with 4 record of id column, values are 1 | A)我们有一个包含4列id列的表,值为1 | 2 | 2 | 3 | 3 | 4 in respective 4 rows. 分别为4行4。
B) IF perform select * from TABLE_NAME:
it returned all record from table in order 1 | B)如果select * from TABLE_NAME:
执行select * from TABLE_NAME:
它按顺序1 |返回表中的所有记录 2 | 2 | 3 | 3 | 4 . 4。
C) If we need total(eg limit ) 1 record and it should start from offset index 2, then use C)如果我们需要总计(例如限制 )1记录并且它应该从偏移索引2开始,那么使用
select * from TABLE_NAME limit 1 offset 2
This will return record index | 这将返回记录索引| 3 | 3 | as request limit = 1 & offset index = 2. as request limit = 1&offset index = 2。
Same can be achieved using select * from company limit 2, 1;
使用select * from company limit 2, 1;
可以实现相同的目标select * from company limit 2, 1;
similar of what @laalto has mentioned. 类似于@laalto所提到的。
Note, here 2 is offset & 1 is limit(order reverse). 注意,这里2是偏移,1是限制(顺序反转)。
Since Android SDK do not provide separate attribute to set offset, in that case last 'limit' attribute of SQLiteDatabase.query(..., limit) can be used as limit 2, 1
. 由于Android SDK不提供单独的属性来设置偏移量,因此在这种情况下,SQLiteDatabase.query(...,limit)的最后“限制”属性可以用作limit 2, 1
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.