I am currently using greenDAO as the ORM for my Android Application. I ran into an issue when trying to execute a GROUPBY clause.
greenDAO does not have API / helper methods for performing groupby clauses, so I decided to use query() or queryRaw() methods available for the AbstractDAO class, where I can pass a valid SQL query. BUT, both these methods return a java.util.List, so what confuses me is that how can I get values of column aliases in the result?
Eg,
SELECT COUNT(ID) AS NUMOFRECORDS, NAME FROM PERSONS GROUP BY AGE
My entity will have NAME and AGE fields, but I created a column alias NUMOFRECORDS, which is not part of the Entity.
Appreciate your help!
This is a alternative solution for your question:
Include the ORDER BY insize of Where.
Ex:
List<Taxi> list = daoSession.getDaoTaxi().queryBuilder().where(new WhereCondition.StringCondition("1 GROUP BY cant_aciento")).list();
I'm stuck with a similar problem. It seems that greenDao doesn't support GROUP BY querys and it won't change in the future, according to what they said here:
GROUP BY is SQL-ish, so stick to SQL. greenDAO is about entities, where GROUP BY is unsupported.
Related
Is there any way I can create and drop tables similar to a 'RawQuery'?
I tried with a #RawQuery annotation (which it would be the perfect solution for me) but when I am compiling I get an error saying methods annotated with RawQuery can't return void.
I read only SELECT, UPDATE and DELETE statements are allowed when using #Query.
I would like to achieve the "creation or deletion of tables" by passing a tablename as a parameter, something like the following:
#Query("DROP TABLE :name")
void deleteTable (String name);
Any ideas on how to achieve this?
Thanks!
Official doc states that,
RawQuery serves as an escape hatch where you can build your own SQL query at runtime but still use Room to convert it into
objects.
RawQuery methods must return a non-void type. If you want to execute a raw query that does not return any value, use
RoomDatabase#query methods.
or use it like,
#RawQuery
int deleteTable (SupportSQLiteQuery query); //We can return int status like it used to return with database.delete()
//Usage
dao.deleteTable(
new SimpleSQLiteQuery("DROP TABLE tablename")
)
The ting is, wit Room, you don't have to "drop" tables, the tables re created based on your entity classes (annotated with #Entity).
As far as I know, you usually need to drop tables in case the columns change or there are some updates on the "structure", with Room there's no point in doing this unless you change the structure of your entity that can't be automatically handled by the migration. In this case, Room gives you the chance to do the migration by yourself. Check the documentation here: https://developer.android.com/training/data-storage/room/migrating-db-versions
But like the documentation states, be really careful with this.
Is it possible to make two orderBy statements in one query. Say i wanna order my data after column 1 and afterwards after column 2. What would be the best way to do that?
Sincerely
Jesper
You just say ORDER BY Column1, Column2. If you are using the orderBy argument of one of the query methods, then remove the prefixing ORDER BY as it is inserted for you when building the query.
I'm attempting to delete all rows in one table that do not have a corresponding ID in another table. Since apparently SQLite does not support joins in deletes I am trying to do something along these lines:
DELETE FROM my_table WHERE my_id NOT IN (SELECT _id FROM my_table2);
However, I apparently can not use rawQuery since it returns a cursor so I have to use the delete function. I'm having some trouble getting this working. Here is the query I'm trying:
mDb.delete("my_table", "my_id NOT IN ?", new String[]{"(SELECT _id FROM my_table2)"});
Thanks.
You shouldn't use a .rawQuery, as you stated, but you can use .execSQL() to accomplish it. I regularly use it for deletions myself.
I think the only way is to execute your select and dynamically combine your WHERE clause.
You have to use execSQL instead rawQuery because rawQuery is used for the statement that return data and execSQL is used for the statements that don't return data like DELETE
Really all I want to do is say the query SELECT DISTINCT column FROM table but I can't figure out how to structure it in the enourmous query methods that are part of SQLiteDatabase
I'm just trying to get the names of all contacts in a table.
You seem to know the sql query you want to run. Have you tried using rawQuery()?
You will probably find this version of the SQLiteDatabase#query method most useful.
I have an SQL statement that I can use to return distinct rows from my Android sqlite3 database and I would like to pass it through a ContentProvider's query.
For example:
select lastName from peopleTable where upper(lastName) like upper("%smith%");
needs to be
select DISTINCT lastName from peopleTable where upper(lastName) like upper("%smith%");
Is there a clean way to pass the extra keywords to the select statement?
This isn't what I would call a "Good Idea", but depending on the CP, you can modify your projection such that the first entry in the projection is "DISTINCT Column" instead of just "Column". This seems to work as long as the ContentProvider is backed by a database and no modifications are made to your projection. I will re-iterate though, that this may not be the best future-proof idea as this "feature" isn't documented and more a matter of how queries are put together with the SQLiteDatabase class. If you know how the ContentProvider was built, then you can tell up-front whether or not this will work.