首页 > 解决方案 > Android Studio - 房间查询结果与预期不同

问题描述

我很难理解为什么同一数据库的相同查询在我的本地测试环境(我的计算机)上是正确的,而在我的设备/模拟器上是错误的。

数据库实际上是相同的(从模拟器复制到计算机)。

SELECT * FROM (
    SELECT name, max(date_col) as date_col, value FROM tbl
    WHERE date_col <= '2021-06-30'
    GROUP BY name
    UNION 
    SELECT name, min(date_col) as date_col, value FROM tbl
    GROUP BY name
    ORDER BY date_col DESC
)
GROUP BY name

该表的架构是(id, date_col, name, value).

我要做的是选择与提供的日期最接近的所有行。我不太确定这是最好的方法,所以欢迎提出任何建议

在我的计算机(SQLITE v3.27.2)中尝试此查询时,它按预期工作,并且在设备/模拟器上测试时(尝试了多个 API 级别,例如 23、27、28),它们都失败了。

编辑:表格数据:

|name |date_col  |value|
|-----|----------|-----|
|NAME6|2021-06-29|71   |
|NAME7|2021-06-29|80   |
|NAME1|2021-06-29|2925 |
|NAME4|2021-06-29|182.0|
|NAME2|2021-06-29|365  |
|NAME3|2021-06-29|81.0 |
|NAME5|2021-06-29|0.25 |
|NAME7|2021-06-27|81.0 |
|NAME1|2021-06-27|3000 |
|NAME5|2021-06-01|0.35 |
|NAME6|2021-06-01|68.0 |
|NAME5|2021-06-28|0.15 |

设备上的结果(日期为 2021-06-28):

|name |date_col  |value|
|-----|----------|-----|
|NAME1|2021-06-27|3000 |
|NAME2|2021-06-29|365.0|
|NAME3|2021-06-29|81.0 |
|NAME4|2021-06-29|182.0|
|NAME5|2021-06-01|0.35 |
|NAME6|2021-06-01|68.0 |
|NAME7|2021-06-27|81.0 |

计算机上的结果(日期为 2021-06-28):

|name |date_col  |value|
|-----|----------|-----|
|NAME1|2021-06-27|3000 |
|NAME2|2021-06-29|365.0|
|NAME3|2021-06-29|81.0 |
|NAME4|2021-06-29|182.0|
|NAME5|2021-06-28|0.15 |
|NAME6|2021-06-01|68.0 |
|NAME7|2021-06-27|81.0 |

如您所见,在此示例中,name5 不同,它应该是 0.15,但在设备上由于某种原因它是 0.35。

这些差异的原因可能是什么?

非常感谢你!

标签: androidsqliteandroid-sqliteandroid-room

解决方案


SELECT *SQLite 允许带有and的语句GROUP BY,但结果行是任意的。

如果您想在较低的 API 级别使用它,则不能使用可以轻松解决问题的窗口函数,如下所示:

SELECT name, date_col, value 
FROM (
  SELECT *, ROW_NUMBER() OVER (
              PARTITION BY name 
              ORDER BY date_col < '2021-06-28' DESC,
                       abs(strftime('%s', date_col) - strftime('%s', '2021-06-28'))
                       
            ) rn
  FROM tbl
)
WHERE rn = 1
ORDER BY name;

您可以使用相关子查询:

SELECT t1.name, t1.date_col, t1.value 
FROM tbl t1
WHERE t1.date_col = (
  SELECT t2.date_col 
  FROM tbl t2
  WHERE t2.name = t1.name 
  ORDER BY date_col < '2021-06-28' DESC,
           abs(strftime('%s', t2.date_col) - strftime('%s', '2021-06-28'))
  LIMIT 1
)
ORDER BY name;

请参阅演示


推荐阅读