如何从 android 中的房间数据库中的单个查询获取项目列表和列值的总和
How to get list of items and sum of values of a column from a single query in room database in android
我想在我的应用程序中显示日期明智的项目列表。该列表将有一个 header,其中包含日期和列值的总和。
24.12.2021
25
Book1
10
Book2
05
Book3
10
这是实体:
@Entity(tableName = "books")
public class Books {
@PrimaryKey(autoGenerate = true)
@ColumnInfo(name = "id")
private int id;
@ColumnInfo(name = "date")
@TypeConverters({TimestampConverter.class})
private long mDate;
@ColumnInfo(name = "quantity")
private double mQuantity;
@ColumnInfo(name = "name")
private String mName;
我正在尝试使用嵌套的 recyclerview 并创建了一个 Parent class :
public class ParentEntry {
private double totalBooks;
private long dateToday;
public List<Books> books;
}
这是道:
@Query("SELECT SUM(quantity) as totalBooks, date as dateToday, * FROM books GROUP BY date ORDER
BY date Asc ")
LiveData<List<ParentEntry>> getAllParentEntries();
但我收到以下错误:
错误:无法弄清楚如何从游标读取此字段。
警告:查询 returns 一些未使用的列 [id, date, quantity, name]。您可以在字段上使用 @ColumnInfo 注释来指定映射。您可以使用 @RewriteQueriesToDropUnusedColumns 注释该方法,以指示 Room 重写您的查询以避免获取未使用的列。 Parent条目中有一些查询未返回的字段 [books]。如果不应该从结果中读取它们,您可以使用 @Ignore 注释标记它们。您可以通过使用 @SuppressWarnings(RoomWarnings.CURSOR_MISMATCH) 注释该方法来抑制此警告。 query:totalBooks、dateToday、id、date、quantity、name 返回的列。 Parent条目中的字段:totalBooks、dateToday、books。
LiveData getAllParentEntries();
如何在单个查询中查询数量列和日期的列表和总和?非常感谢任何帮助。
为了在 POJO 中构建列表,您需要一个@Relation。
所以 ParentEntity 需要类似于:-
class ParentEntry {
long dateToday;
double totalBooks;
@Relation(entity = Books.class,
parentColumn = "dateToday",
entityColumn = "date")
List<Books> booksList;
}
因此您需要一个查询,然后检索列名与成员变量名匹配的非列表值(dateToday 和 totalBooks),这可能是 :-
@Transaction
@Query("SELECT date AS dateToday, total(quantity) AS totalBooks FROM books GROUP BY date ORDER BY date ASC;")
abstract List<ParentEntryV2> getParentEntries();
- 注意使用总计而不是总和,因为总计保证 return 浮点值,总和可以 return null 并且还可以抛出整数溢出异常。见 https://sqlite.org/lang_aggfunc.html#sumunc
例如来自一本书 table :-
使用:-
for(ParentEntryV2 pev2: dao.getParentEntries()) {
Log.d("PEINFO_V2","Date is " + pev2.dateToday + " TotalBooks is " + pev2.totalBooks + " Number of Books in list is " + pev2.booksList.size());
for (Books b: pev2.booksList) {
Log.d("PEINFO_V2","\tBook is " + b.getmName() + " quantity is " + b.getmQuantity());
}
}
结果:-
D/PEINFO_V2: Date is 1640124943 TotalBooks is 30.0 Number of Books in list is 3
D/PEINFO_V2: Book is Book1 quantity is 10.0
D/PEINFO_V2: Book is Book2 quantity is 10.0
D/PEINFO_V2: Book is Book3 quantity is 10.0
D/PEINFO_V2: Date is 1640211343 TotalBooks is 30.0 Number of Books in list is 3
D/PEINFO_V2: Book is Book4 quantity is 10.0
D/PEINFO_V2: Book is Book5 quantity is 10.0
D/PEINFO_V2: Book is Book6 quantity is 10.0
D/PEINFO_V2: Date is 1640297743 TotalBooks is 30.0 Number of Books in list is 3
D/PEINFO_V2: Book is Book7 quantity is 10.0
D/PEINFO_V2: Book is Book8 quantity is 10.0
D/PEINFO_V2: Book is Book9 quantity is 10.0
额外
关于日期问题(即您只想要 date/time 中的日期部分)那么您可以使用以下但它需要 2 个查询和一个抽象 class 而不是一个接口和其他在 Dao 的单个事务中调用两个查询的函数。道的存在:-
@Transaction
@Query("SELECT date AS dateToday, total(quantity) AS totalBooks FROM books GROUP BY date(date/:timefactor,'unixepoch') ORDER BY date ASC;")
abstract List<ParentEntryV2> getParentEntries(long timefactor);
@Query("SELECT * FROM books WHERE date(date/:timefactor,'unixepoch')=date(:date/:timefactor,'unixepoch')")
abstract List<Books> getBooksPerDate(long date,long timefactor);
@Transaction
@Query("")
List<ParentEntryV2> getParentEntriesV2() {
List<ParentEntryV2> parentEntryV2List = getParentEntries(1 /* 1000 if precision to millisecs */);
for(ParentEntryV2 pe: parentEntryV2List) {
pe.booksList = getBooksPerDate(pe.dateToday,1 /* 1000 if precision to millisecs */);
}
return parentEntryV2List;
}
- 请注意,timefactor 允许 1 或 1000 用于在精度为 1 秒 (1) 和精度为毫秒 (1000) 之间切换。
- 虽然第一个查询基本相同,除了 GROUP BY,第二个查询用所需的书目(与日期匹配的书)覆盖书目(完全 date/time 匹配的书)。
我想在我的应用程序中显示日期明智的项目列表。该列表将有一个 header,其中包含日期和列值的总和。
24.12.2021 | 25 |
---|---|
Book1 | 10 |
Book2 | 05 |
Book3 | 10 |
这是实体:
@Entity(tableName = "books")
public class Books {
@PrimaryKey(autoGenerate = true)
@ColumnInfo(name = "id")
private int id;
@ColumnInfo(name = "date")
@TypeConverters({TimestampConverter.class})
private long mDate;
@ColumnInfo(name = "quantity")
private double mQuantity;
@ColumnInfo(name = "name")
private String mName;
我正在尝试使用嵌套的 recyclerview 并创建了一个 Parent class :
public class ParentEntry {
private double totalBooks;
private long dateToday;
public List<Books> books;
}
这是道:
@Query("SELECT SUM(quantity) as totalBooks, date as dateToday, * FROM books GROUP BY date ORDER
BY date Asc ")
LiveData<List<ParentEntry>> getAllParentEntries();
但我收到以下错误:
错误:无法弄清楚如何从游标读取此字段。
警告:查询 returns 一些未使用的列 [id, date, quantity, name]。您可以在字段上使用 @ColumnInfo 注释来指定映射。您可以使用 @RewriteQueriesToDropUnusedColumns 注释该方法,以指示 Room 重写您的查询以避免获取未使用的列。 Parent条目中有一些查询未返回的字段 [books]。如果不应该从结果中读取它们,您可以使用 @Ignore 注释标记它们。您可以通过使用 @SuppressWarnings(RoomWarnings.CURSOR_MISMATCH) 注释该方法来抑制此警告。 query:totalBooks、dateToday、id、date、quantity、name 返回的列。 Parent条目中的字段:totalBooks、dateToday、books。
LiveData getAllParentEntries();
如何在单个查询中查询数量列和日期的列表和总和?非常感谢任何帮助。
为了在 POJO 中构建列表,您需要一个@Relation。
所以 ParentEntity 需要类似于:-
class ParentEntry {
long dateToday;
double totalBooks;
@Relation(entity = Books.class,
parentColumn = "dateToday",
entityColumn = "date")
List<Books> booksList;
}
因此您需要一个查询,然后检索列名与成员变量名匹配的非列表值(dateToday 和 totalBooks),这可能是 :-
@Transaction
@Query("SELECT date AS dateToday, total(quantity) AS totalBooks FROM books GROUP BY date ORDER BY date ASC;")
abstract List<ParentEntryV2> getParentEntries();
- 注意使用总计而不是总和,因为总计保证 return 浮点值,总和可以 return null 并且还可以抛出整数溢出异常。见 https://sqlite.org/lang_aggfunc.html#sumunc
例如来自一本书 table :-
使用:-
for(ParentEntryV2 pev2: dao.getParentEntries()) {
Log.d("PEINFO_V2","Date is " + pev2.dateToday + " TotalBooks is " + pev2.totalBooks + " Number of Books in list is " + pev2.booksList.size());
for (Books b: pev2.booksList) {
Log.d("PEINFO_V2","\tBook is " + b.getmName() + " quantity is " + b.getmQuantity());
}
}
结果:-
D/PEINFO_V2: Date is 1640124943 TotalBooks is 30.0 Number of Books in list is 3
D/PEINFO_V2: Book is Book1 quantity is 10.0
D/PEINFO_V2: Book is Book2 quantity is 10.0
D/PEINFO_V2: Book is Book3 quantity is 10.0
D/PEINFO_V2: Date is 1640211343 TotalBooks is 30.0 Number of Books in list is 3
D/PEINFO_V2: Book is Book4 quantity is 10.0
D/PEINFO_V2: Book is Book5 quantity is 10.0
D/PEINFO_V2: Book is Book6 quantity is 10.0
D/PEINFO_V2: Date is 1640297743 TotalBooks is 30.0 Number of Books in list is 3
D/PEINFO_V2: Book is Book7 quantity is 10.0
D/PEINFO_V2: Book is Book8 quantity is 10.0
D/PEINFO_V2: Book is Book9 quantity is 10.0
额外
关于日期问题(即您只想要 date/time 中的日期部分)那么您可以使用以下但它需要 2 个查询和一个抽象 class 而不是一个接口和其他在 Dao 的单个事务中调用两个查询的函数。道的存在:-
@Transaction
@Query("SELECT date AS dateToday, total(quantity) AS totalBooks FROM books GROUP BY date(date/:timefactor,'unixepoch') ORDER BY date ASC;")
abstract List<ParentEntryV2> getParentEntries(long timefactor);
@Query("SELECT * FROM books WHERE date(date/:timefactor,'unixepoch')=date(:date/:timefactor,'unixepoch')")
abstract List<Books> getBooksPerDate(long date,long timefactor);
@Transaction
@Query("")
List<ParentEntryV2> getParentEntriesV2() {
List<ParentEntryV2> parentEntryV2List = getParentEntries(1 /* 1000 if precision to millisecs */);
for(ParentEntryV2 pe: parentEntryV2List) {
pe.booksList = getBooksPerDate(pe.dateToday,1 /* 1000 if precision to millisecs */);
}
return parentEntryV2List;
}
- 请注意,timefactor 允许 1 或 1000 用于在精度为 1 秒 (1) 和精度为毫秒 (1000) 之间切换。
- 虽然第一个查询基本相同,除了 GROUP BY,第二个查询用所需的书目(与日期匹配的书)覆盖书目(完全 date/time 匹配的书)。