Android-комната + оконные функции

Я пытаюсь использовать оконные функции в запросе комнаты. Парсер жалуется на мой запрос. Я просто пытаюсь добавить выражение «ROW_NUMBER() OVER (ORDER BY column)» в свой оператор выбора. Без этого выражения запрос выполняется правильно.

Ошибка парсера:

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}

person Jerome Dupont    schedule 08.03.2019    source источник


Ответы (3)


В Android Room не будет использоваться версия SQLite, включающая функции Windows, для которых требуется SQLite 3.25.0 или более поздней версии, как указано ниже:

Поддержка оконных функций была добавлена ​​в SQLite в версии 3.25.0 (15 сентября 2018 г.). Разработчики SQLite использовали документацию по оконным функциям PostgreSQL в качестве основного справочника по тому, как должны вести себя оконные функции. Для PostgreSQL было выполнено множество тестов, чтобы убедиться, что оконные функции работают одинаково как в SQLite, так и в PostgreSQL. Функции окна

Последний Android API 28, похоже, использует 3.19, поскольку он не указан в android. database.sqlite, поэтому он будет использовать то же, что и API 27.

Таким образом, SQLite рассматривает неизвестное предложение как синтаксическую ошибку.

person MikeT    schedule 08.03.2019
comment
Спасибо Майк за объяснение, это имеет смысл. - person Jerome Dupont; 20.03.2019
comment
@JeromeDupont Какое решение? - person Jaimin Modi; 09.06.2021

Это синтаксическая ошибка в вашем SQL-запросе.

Убедитесь, что при формировании запроса ставьте пробел в конце каждой строки.

person Amit raj    schedule 25.06.2020

Действительно, версия SQLite, встроенная в Android, еще не предоставляет оконных функций. Но я хочу опубликовать обходной путь, вдохновленный этим вопросом: Как использовать ROW_NUMBER в 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' часть запроса.

person Nicolas Prugne    schedule 05.12.2020