简体   繁体   English

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

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM