我尝试在“房间查询”中使用“窗口函数”。解析器抱怨我的查询。我只是尝试在我的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}
答案 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'
部分。