带偏移的android sqlite查询不返回所需的行

时间:2015-05-26 12:38:49

标签: java android sqlite android-sqlite

我正在使用以下代码获取通知列表(总行数为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行,然后开始从那里开始行,这是我的想法或我的查询是错误的。我在这做错了什么?感谢

3 个答案:

答案 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