I have problem with queries in Room. I have entity where is String field called Type. I want to make a query that will allow me to get the sum of objects by type. So if I have 4 expenses with Bills type I want to get them as a sum.
Expense:
#Entity(tableName = "expense_table")
public class Expense {
#PrimaryKey(autoGenerate = true)
private int expenseId;
private String note;
private Double value;
private String type;
Table of defined types:
private String[] expenses = {"Bills", "Car", "Child", "Clothes", "Entertainment", "Education", "Electronics",
"Food", "Health", "Home", "Pet", "Shopping", "Transport", "Travel", "Others"};
Query in Dao:
#Query("SELECT SUM(value) FROM expense_table GROUP BY type")
LiveData<List<Double>> getTotalType();
In query above I'm getting the sum of every single type, but I do not know which one is which. I need this information because I want to set sum of types in chart. So my question is: Is it possible to make one query to get every single sum with name of type, or rather I need to make every query for every single type?
You need to add the type to your query and create a POJO to hold both values(the type and its corresponding total):
#Query("SELECT type, SUM(value) as total FROM expense_table GROUP BY type")
LiveData<List<TypeWithSum>> getTotalType();
where TypeWithSum is:
public class TypeWithSum {
private String type;
private double total;
public TypeWithSum(String type, double total) {
this.type = type;
this.total = total;
}
}
Related
I'm using Room library to retrive a List without duplicates for property "text".
This is the code of the query in MyObjectDao class:
#Query("SELECT DISTINCT * FROM historyentity WHERE text LIKE :inputText || '%'")
List<MyObject> findByText(String inputText);
I also post MyObject class:
#Entity
public class MyObject {
#PrimaryKey(autoGenerate = true)
public int uid;
#ColumnInfo(name = "text")
public String text;
#ColumnInfo(name = "timestamp")
public Long timestamp;
}
Anyway I still get get results with duplicates for field "text". How can I get a List that does not contains duplicates on field "text"?
For example if I have the following three elements in the database
database.addMyObject(new MyObject("dog", System.currentTimeInMills());
database.addMyObject(new MyObject("cat", System.currentTimeInMills());
database.addMyObject(new MyObject("dog", System.currentTimeInMills());
when I call my query I want to get only the first two elements.
If you want just list with unique text values you can try this one:
#Query("SELECT DISTINCT text FROM historyentity WHERE text LIKE :inputText || '%'")
List<String> findByText(String inputText); // <-- changed type to List<String>
UPDATE
You can try this query (it gets only one item with text value - with maximal id - or you can use maximal (or minimal) timestamp):
Select * from historyentity as t1
INNER JOIN (select text,max(uid) as uid from historyentity WHERE text LIKE :inputText group by text) t2
ON t1.text = t2.text and t1.uid = t2.uid
I'm working on Room database, and I want to get two columns values(Category and total amount) from IncomeExpense table by comparing distinct values in category column. Let me explain, for example in category column there are 4 rows which have same value(cash), what I want is to calculate total amount of amount column where category is cash and category value (which is cash in this case).
I take these categories values from another table (Category table) in which user can add edit or delete categories.
The problem is that I don't know how to compare category with those values user added in category column which dynamic in this case.
This is my Entity class.
#Entity
public class IncomeExpense {
#PrimaryKey(autoGenerate = true)
private int id =0;
private String type;
private int amount;
private String category;
private String date;
private String time;
private String mode;
private String note;
This is Dao class where I have to write this query
#Query("SELECT SUM(amount), category from IncomeExpense WHERE category like 'What should I write here to get these values in this case'");
I just want to get the total amount and category value in this case
you can use group by clause, this will return a list on IncomeExpense but amount will be grouped as per category
#Query("SELECT SUM(amount) as amount,category from IncomeExpense GROUP BY category");
public List<IncomeExpense> getCategoryPrice();
For Example:
Database Has:
[ (10, Cash), (50, Cash), (20, Credit), (10, Credit) ]
The above query will return
[ (60, Cash), (30, Credit) ]
My database contains a list of these "Movement" class:
#PrimaryKey (autoGenerate = true)
private int NumeroDeOperacion;
private int FechaYear;
private int FechaMonth;
private int FechaDay;
private String TipoOperacion;
private String Category;
private String Notas;
private float Quantity;
In one of my queries I'd like to retrieve only Category and Quantity so I created another POJO object like this:
public class Category {
#ColumnInfo(name = "Category")
public String name;
#ColumnInfo(name = "Quantity")
public float quantity;
public Category(){}
}
What I'm triying to get is all the different Category in a specific year and the SUM of all Quantity.
So, let's say I have something like this:
Category Quantity
A 5
B 10
C 5
A 15
B 20
I'd like to get:
Category Quantity
A 20
B 30
C 5
I tried with this query but it is only getting the last entry of each Category:
#Query("SELECT DISTINCT Category, Quantity FROM OperacionesTable WHERE FechaYear = :year GROUP BY CategoryORDER BY Quantity DESC")
LiveData<List<Category>> getGastosCategoryTotalsInYear(int year);
Any help would be much appreciated.
Thanks in advance
To sum the quantities, you have to use SUM.
Also, there is no need for DISTINCT, since GROUP BY already takes care of that. My guess is that you added distinct, because there was an error. The error was there, because Quantity was neither in the group by columns, nor used in an aggregate function. This is typically an error (except in MySQL, which will just give you a random result).
Anyway, this should do the trick:
SELECT
Category,
SUM(Quantity) as TotalQuantity -- Column alias, to give the column a proper name
FROM
OperacionesTable
WHERE
FechaYear = :year
GROUP BY
Category
ORDER BY SUM(Quantity) DESC
I have a table that looks like following
#Entity
#JsonIgnoreProperties(ignoreUnknown = true)
public class Product
{
#PrimaryKey
#ColumnInfo(name = "ID")
#JsonProperty("ID")
public int id;
#ColumnInfo(name = "Name")
#JsonProperty("Name")
public String name;
#ColumnInfo(name = "Documents")
#JsonProperty("Documents")
#TypeConverters(DocumentConverter.class)
public List<Document> documents;
}
//...
#TypeConverters(DocumentConverter.class)
#JsonIgnoreProperties( ignoreUnknown = true )
#JsonTypeName("Documents")
public class Document
{
#JsonProperty("Name")
public String name;
#JsonProperty("URL")
public String url;
}
I am able to retrieve a product based on its name by doing something like this
#Query("SELECT * FROM Product WHERE Name = :name")
List<Product> getProducts(String name);
And I would then be able to access the list of documents from each Product object. However I would also like to only deal with Products that has certain documents. I could get all Products via a query like above, then manually filter for the documents that I want, but it becomes quite a pain when I'm only looking for very specific documents.
Is it possible to also query based on Document variables without it being a separate table?
Something like...
#Query("SELECT * FROM Product WHERE Name = :name AND Document.name = :documentName")
List<Product> getProducts(String name, String documentName);
Thanks.
You could use LIKE sql statement to search inside your json column with converted documents list. Example:
Assume that we have document converted like this for storing in db:
{
name: "Title",
url: "Your_url"
}
So your query for product with such document in list should be like this:
SELECT * FROM Product WHERE Name = :name AND Documents LIKE :documentLikeExpr
Where
String documentLikeExpr = "%name: \"Title\"%";
% in expression mean zero, one or multiple characters.
So the only thing we are doing here - is searching for part of string inside column using SQL language features.
You cannot query a Document class variables as it is not stored as a separate table. #TypeConverter annotation converts your Document list to some predefined data types such as String. Basically it stores list of Document as a string Gson in a column of Product table, So we cannot access the field name of Document class in SQL query like Document.name.
Read the Option #2 given by #CommonsWare here
So, to access it you have to create a separate table for Document.
I'm trying to get id column from my database, ad it to ArrayList and to each id add "\t0",
My database is created using Room, i have a lot of column which one of them is
#PrimaryKey(autoGenerate = true)
private int id;
I am operating using ItemDAO and i have there function
#Query("SELECT * FROM item")
List<Item> getItems();
Which writes to ArrayList<Items> all of contents
I was thinking of running it trough the loop getting id and adding to ArrayList<String> but this doesn't seems to be eficient.
Your DAO:
#Query("SELECT Id FROM item")
List<Integer> getAllIds();
Your model:
#ColumnInfo(name = "Id")
#PrimaryKey(autoGenerate = true)
private int id;
In you query SELECT * FROM item * means select All, put there your column name and you will get list of objects from that column
Example: Select all items in id column SELECT id FROM item
I tried to modify and test #Valgaal 's solution. It turns out that Room can also return other type of values, more than just id (or integer).
For example, you can write an item class like this:
#Entity(tableName = Item.TABLE_NAME)
public class Item {
public static final String TABLE_NAME = "ItemsTable";
public static final String COL_DESC = "Description";
#PrimaryKey(autoGenerate = true)
private int id;
#ColumnInfo(name = COL_DESC)
private String description;
// getter & setter...
}
And then, you can write Dao like this:
#Dao
public interface ItemDao {
#Query("SELECT * FROM " + Item.TABLE_NAME)
List<Item> getItems();
#Query("SELECT " + Item.COL_DESC + " FROM " + Item.TABLE_NAME)
List<String> getItemDescriptions();
}
And it's functional as it should be.
I guess all of the other data types that Room can save (including custom types?) can be queried (and returned lists of specific column data) by the same logic above. Hope this would help someone in the future!
For returning multiple columns, create a pojo class that can be set as a return type for your DAO function
Note the select query should contain the Pojo class variable name (can be done via AS keyword)
Detailed answer here
https://stackoverflow.com/a/50802209/1029110
I landed on this question for my issue...but didnt find answer. So this may help others.