Android Room +视窗功能

时间:2019-03-08 16:43:45

标签: android android-sqlite android-room

我尝试在“房间查询”中使用“窗口函数”。解析器抱怨我的查询。我只是尝试在我的select语句中添加“ ROW_NUMBER()OVER(ORDER BY列)”表达式。没有此表达式,查询将正确运行。

解析器错误:

extraneous input '(' expecting {<EOF>, ';', ',', K_ALTER, K_ANALYZE, 
K_ATTACH, K_BEGIN, K_COMMIT, K_CREATE, K_DELETE, K_DETACH, K_DROP, 
K_END, K_EXCEPT, K_EXPLAIN, K_FROM, K_GROUP, K_INSERT, K_INTERSECT, 
K_LIMIT, K_ORDER, K_PRAGMA, K_REINDEX, K_RELEASE, K_REPLACE, 
K_ROLLBACK, K_SAVEPOINT, K_SELECT, K_UNION, K_UPDATE, K_VACUUM, 
K_VALUES, K_WHERE, K_WITH, UNEXPECTED_CHAR}
mismatched input ')' expecting {<EOF>, ';', ',', '=', '*', '+', '-', 
'||', '/', '%', '<<', '>>', '&', '|', '<', '<=', '>', '>=', '==', '!=', 
'<>', K_ALTER, K_ANALYZE, K_AND, K_ASC, K_ATTACH, K_BEGIN, K_BETWEEN, 
K_COLLATE, K_COMMIT, K_CREATE, K_DELETE, K_DESC, K_DETACH, K_DROP, 
K_END, K_EXPLAIN, K_GLOB, K_IN, K_INSERT, K_IS, K_ISNULL, K_LIKE, 
K_LIMIT, K_MATCH, K_NOT, K_NOTNULL, K_OR, K_PRAGMA, K_REGEXP, 
K_REINDEX, K_RELEASE, K_REPLACE, K_ROLLBACK, K_SAVEPOINT, K_SELECT, 
K_UPDATE, K_VACUUM, K_VALUES, K_WITH, UNEXPECTED_CHAR}
extraneous input ')' expecting {<EOF>, ';', ',', K_ALTER, K_ANALYZE, 
K_ATTACH, K_BEGIN, K_COMMIT, K_CREATE, K_DELETE, K_DETACH, K_DROP, 
K_END, K_EXPLAIN, K_INSERT, K_LIMIT, K_PRAGMA, K_REINDEX, K_RELEASE, 
K_REPLACE, K_ROLLBACK, K_SAVEPOINT, K_SELECT, K_UPDATE, K_VACUUM, 
K_VALUES, K_WITH, UNEXPECTED_CHAR} extraneous input 'add_permutation' 
expecting {<EOF>, ';', ',', '=', '*', '+', '-', '||', '/', '%', '<<', 
'>>', '&', '|', '<', '<=', '>', '>=', '==', '!=', '<>', K_ALTER, 
K_ANALYZE, K_AND, K_ASC, K_ATTACH, K_BEGIN, K_BETWEEN, K_COLLATE, 
K_COMMIT, K_CREATE, K_DELETE, K_DESC, K_DETACH, K_DROP, K_END, 
K_EXPLAIN, K_GLOB, K_IN, K_INSERT, K_IS, K_ISNULL, K_LIKE, K_LIMIT, 
K_MATCH, K_NOT, K_NOTNULL, K_OR, K_PRAGMA, K_REGEXP, K_REINDEX, 
K_RELEASE, K_REPLACE, K_ROLLBACK, K_SAVEPOINT, K_SELECT, K_UPDATE, 
K_VACUUM, K_VALUES, K_WITH, UNEXPECTED_CHAR}

3 个答案:

答案 0 :(得分:0)

Android Room将不会使用包含Windows功能的SQLite版本,该版本要求使用SQLite 3.25.0或更高版本:-

  

窗口功能支持已添加到SQLite的发行版中   3.25.0(2018-09-15)。 SQLite开发人员使用PostgreSQL窗口函数文档作为他们如何使用窗口的主要参考   功能应该表现出来。许多测试用例已经针对   PostgreSQL确保窗口函数在Windows中以相同的方式运行   SQLite和PostgreSQL。 Window Functions

由于android.database.sqlite中未列出最新的Android API 28,因此似乎使用3.19,因此它将使用与API 27相同的方式。

因此,SQLite将此未知子句视为语法错误。

答案 1 :(得分:0)

这是您的SQL查询中的语法错误。

请确保在形成查询时,在每行末尾添加一个空格。

答案 2 :(得分:0)

实际上,Android中嵌入的SQLite版本尚不提供窗口功能。但是我想发布一个受以下问题启发的变通方法:How to use ROW_NUMBER in sqlite,如果其他人在Android上都在为此苦苦挣扎。

例如在这种关系中:

| id | value | updated_at                     |
-----------------------------------------------
| 1  | yes   | 2020-11-26 11:27:45.662 +00:00 |
| 3  | yes   | 2020-11-27 17:19:45.662 +00:00 |
| 4  | yes   | 2020-11-26 11:21:45.662 +00:00 |
| 6  | no    | 2020-11-26 14:42:45.662 +00:00 |
| 9  | yes   | 2020-11-27 15:08:45.662 +00:00 |
-----------------------------------------------

您可以使用此查询仅获取由与行号相关联的updated_at列排序的“是”行:

SELECT
    id,
    value,
    (
        SELECT
            count(*)
        FROM
            tbl b
        WHERE
            a.updated_at >= b.updated_at
            AND value = 'yes'
    ) AS row_num,
    updated_at
FROM
    tbl a
WHERE
    value = 'yes'
ORDER BY updated_at

它产生以下结果:

| id | value | row_num | updated_at                     |
---------------------------------------------------------
|  4 |   yes |   1     | 2020-11-26 11:21:45.662 +00:00 |
|  1 |   yes |   2     | 2020-11-26 11:27:45.662 +00:00 |
|  9 |   yes |   3     | 2020-11-27 15:08:45.662 +00:00 |
|  3 |   yes |   4     | 2020-11-27 17:19:45.662 +00:00 |
---------------------------------------------------------

请注意,此处通常在窗口函数OVER (ORDER BY updated_at)中出现的ROW_NUMBER子句会被产生WHERE a.updated_at >= b.updated_at列的子查询的row_num子句代替。同样,您需要像在主查询中一样过滤此子查询的行,否则,行号将考虑表的所有行,而您将无法获得预期的结果。这就是查询的AND value = 'yes'部分。