使用 sqlite 查询从 Android 房间获取复杂响应

Get complex response from Android Room with sqlite query

基于对我的问题的回答 here

我有简单的table:

id, name, city

我为它创建了一个 class:

@Entity(tableName = "table2")
data class Table2 @JvmOverloads constructor(
  @PrimaryKey @ColumnInfo(name = "id") val id: Int? = 0,
  @ColumnInfo(name = "name") val name: String? = "",
  @ColumnInfo(name = "city") val city: String? = ""
)

我输入了下一行:

1 John London
2 Mary Paris
3 John Paris
4 Samy London

我想得到这样的结果:

      London  Paris
John    1       1
Mary    0       1
Samy    1       0
Total   2       2

获取 Total 行和 John, Mary and Samy 行并不重要,现在我只想得到一个简单的响应而不需要复杂的查询。

因为我想获得包含 3 个字段的 classes 的响应列表:

city, Int, Int

我为它创建了一个class:

data class CityName constructor(
    val name: String? = "",
    val countLondon: Int? = 0,
    val countParis: Int? = 0
)

接下来我尝试创建一个 SQLite 查询以从 Android 房间获取结果。

@Query("SELECT name, 
    COUNT(CASE WHEN city = :london THEN 1 ELSE 0 END) 'London', 
    COUNT(CASE WHEN city = :paris THEN 1 ELSE 0 END) 'Paris' 
    FROM table2 GROUP BY name")
fun getPivot_CityNameList(london: String, paris: String): List<CityName>

我excluded/included来自查询'London'和'Paris',我交换了一些词等。 但我总是得到这样的结果:

John, countLondon: null, countParis: null
Mary, countLondon: null, countParis: null
Samy, countLondon: null, countParis: null

很容易从 table 中获取子集,例如城市和 ID,或者仅获取某个字段的计数,但是 我不知道如何在一个响应中将子集(名称)与两个计数结合起来。

有什么问题:我的查询或 CityName class 响应? 如何解决?

回答

正确的查询是

SELECT name,
COUNT(CASE WHEN city = :london THEN 1 END) as countLondon, 
COUNT(CASE WHEN city = :paris THEN 1 END) as countParis 
FROM table2 GROUP BY name

如已接受的答案中所述,我错过了 as countLondon 但我也从 CASE 语句

中删除了 ELSE 0

您的 CityName 字段名称应与查询列的别名相匹配。 这就是 Room 将值从 SQLite 游标复制到此 class.

字段的方式

所以更改列的别名,您的代码应该可以工作:

@Query("SELECT name, 
    COUNT(CASE WHEN city = :london THEN 1 ELSE 0 END) as countLondon, // <- change here 
    COUNT(CASE WHEN city = :paris THEN 1 ELSE 0 END) as countParis // <- change here
    FROM table2 GROUP BY name")
fun getPivot_CityNameList(london: String, paris: String): List<CityName>