I try to use a Window Functions in a Room Query. The parser is complaining about my query. I simply try to add a \"ROW_NUMBER() OVER (ORDER BY column)\" expression in my sel
Indeed the SQLite version embedded in Android does not provide window functions yet. But I want to post a workaround inspired by this question: How to use ROW_NUMBER in sqlite, if anyone else is struggling with this on Android.
For example in this relation:
| 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 |
-----------------------------------------------
You can use this query to only get the 'yes' rows ordered by the updated_at column associated to a row number:
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
It produces the following results:
| 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 |
---------------------------------------------------------
Beware that the OVER (ORDER BY updated_at)
clause normally present in the window function ROW_NUMBER
is replaced here by the WHERE a.updated_at >= b.updated_at
clause of the sub-query which produces the row_num
column. Also you need to filter the rows of this sub-query as you do it in the main query, otherwise, the row number will take into account all the rows of the table and you won't get the expected result. That's the AND value = 'yes'
part of the query.