我正在使用以下代码获取通知列表(总行数为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();
}
并且生成的offset = 0的查询是
SELECT Id, Token, Title, Read, Message, Image, CreateDate, CreateDateFA FROM Notifications ORDER BY CreateDate DESC LIMIT 20,0
并且它按预期工作并返回20行,当我将偏移量增加1(偏移= 1)时,它只返回1行,这是正确的,但问题是当偏移量大于1时,查询将是
SELECT Id, Token, Title, Read, Message, Image, CreateDate, CreateDateFA FROM Notifications ORDER BY CreateDate DESC LIMIT 20,2
我觉得它应该跳过20 * 2行,然后开始从那里开始行,这是我的想法或我的查询是错误的。我在这做错了什么?感谢
答案 0 :(得分:14)
LIMIT 20,2
我觉得它应该跳过20 * 2行,然后开始从那里开始行,这是我的想法或我的查询是错误的。
LIMIT 20,2
跳过前20行,最多返回2行。它与LIMIT 2 OFFSET 20
相同。
即使documentation说它反直觉:
LIMIT子句可以指定由逗号分隔的两个标量表达式,而不是单独的OFFSET子句。在这种情况下,第一个表达式用作OFFSET表达式,第二个表达式用作LIMIT表达式。这是违反直觉的,因为当使用OFFSET子句时,两个表达式中的第二个是OFFSET,第一个是LIMIT。这种偏移和限制的逆转是有意的 - 它最大化了与其他SQL数据库系统的兼容性。但是,为了避免混淆,强烈建议程序员使用LIMIT子句的形式,该子句使用&#34; OFFSET&#34;关键字并避免使用带逗号分隔偏移量的LIMIT子句。
如果要实现页面大小为20的结果分页,请使用OFFSET k*20 LIMIT 20
之类的内容,其中k
是从零开始的页码。
答案 1 :(得分:2)
您可以在Cursor
内使用偏移作为&#34;偏移,限制&#34;值:
Cursor cursor = db.query(
TABLE_NAME,
new String[]{COLUMN_NAME_1, COLUMN_NAME_2, COLUMN_NAME_3},
null,
null,
null,
null,
null,
"6,1000");
在这个例子中,我从第7个开始选择了所有行(我想不超过1000行)。这里6是你的偏移,1000是限制。
答案 2 :(得分:1)
这里需要了解LIMIT <offset>, <count>
和&amp; LIMIT <count> OFFSET <offset>
是等价的。
示例:
A)我们有一个包含4列id列的表,值为1 | 2 | 3 |分别为4行4。
B)如果执行select * from TABLE_NAME:
,则按顺序1 |返回表中的所有记录2 | 3 | 4。
C)如果我们需要总计(例如限制)1记录并且它应该从偏移索引2开始,那么使用
select * from TABLE_NAME limit 1 offset 2
这将返回记录索引 | 3 | 作为请求限制= 1&amp;偏移指数= 2。
使用类似@laalto提到的select * from company limit 2, 1;
可以实现同样的效果。
注意,这里2是偏移&amp; 1是限制(逆序)。
由于Android SDK不提供单独的属性来设置偏移量,因此在这种情况下,SQLiteDatabase.query(...,limit)的最后“限制”属性可以用作limit 2, 1
。