SQLite Group By 结果顺序行为更改 3.28.0 起
SQLite Group By results order behaviour change 3.28.0 onwards
我注意到在较新版本的 SQLite 中使用“GROUP BY”的结果顺序存在问题,该问题正在努力解决。当 Android 11 使用 SQLite 3.28.0 时,我第一次注意到它。我现在将其归因于 SQLite 本身的行为变化。
问题是结果的顺序根据版本而改变。我不确定它是错误还是预期行为还是我的错误(尽管这个错误在旧的 SQLite 版本中已经运行了 8 年)。
示例table:
id|year|command |code
1 |2005|TV |A
2 |2005|TV-CD |B
3 |2005|CD |B
4 |2010|TV |B
5 |2015|TV |C
如果我运行下面的命令
SELECT * FROM myTable GROUP BY command ORDER BY _id
在 SQLite 3.22 (Android 10) 或 3.23.1 中,我得到:
2|2005|TV-CD|B
3|2005|CD |B
5|2015|TV |C
这是我想要的...
如果我在 SQLite 3.28 (Android 11) 或更高版本中 运行 使用相同的命令,我会得到
1|2005|TV |A
2|2005|TV-CD|B
3|2005|CD |B
这里有一个 table 的快速示例,如果您想自己尝试一下
CREATE TABLE 'myTable' ('_id' integer PRIMARY KEY ,'year' NUMERIC ,'command' TEXT, 'code' TEXT);
INSERT INTO myTable VALUES ("1","2005","TV","A");
INSERT INTO myTable VALUES ("2","2005","TV-CD","B");
INSERT INTO myTable VALUES ("3","2005","CD","B");
INSERT INTO myTable VALUES ("4","2010","TV","B");
INSERT INTO myTable VALUES ("5","2015","TV","C");
SELECT * FROM myTable GROUP BY command ORDER BY _id
https://www.jdoodle.com/execute-sql-online/ 对测试很有用,因为它允许您即时更改 SQLite 版本。
我找到了一个解决方案并且可以确认它在两个版本的 SQLite 中都有效
SELECT _id,MAX (year),command,code FROM myTable GROUP BY command ORDER BY _id
正如我在评论中提到的,查询的结果如下:
SELECT * FROM myTable GROUP BY command
是 unpredictable,因为 GROUP BY
应该只用于聚合,比如:
SELECT command, MAX(year) AS max_year
FROM myTable
GROUP BY command
这将 return 每个 command
的最大值 year
。
因此,如果 GROUP BY
和 SELECT * ...
的行为在较新版本中发生了变化,如果您没有使用此类查询,则应该不是问题。
根据我在你的问题中读到的内容,你期望每个 command
行的结果中最大 id
.
在标准 sql 中并且没有 window 函数,大多数版本的 android SQLite 仍然不支持这些函数,您可以先聚合然后加入 table.
但是,SQLite 有一个 documented feature 可供使用,因此您可以使用 裸 列。
这是有效的:
SELECT MAX(_id) AS _id, year, command, code
FROM myTable
GROUP BY command
ORDER BY _id
对于每个 command
.
,您将获得最大 _id
的行
我注意到在较新版本的 SQLite 中使用“GROUP BY”的结果顺序存在问题,该问题正在努力解决。当 Android 11 使用 SQLite 3.28.0 时,我第一次注意到它。我现在将其归因于 SQLite 本身的行为变化。 问题是结果的顺序根据版本而改变。我不确定它是错误还是预期行为还是我的错误(尽管这个错误在旧的 SQLite 版本中已经运行了 8 年)。
示例table:
id|year|command |code
1 |2005|TV |A
2 |2005|TV-CD |B
3 |2005|CD |B
4 |2010|TV |B
5 |2015|TV |C
如果我运行下面的命令
SELECT * FROM myTable GROUP BY command ORDER BY _id
在 SQLite 3.22 (Android 10) 或 3.23.1 中,我得到:
2|2005|TV-CD|B
3|2005|CD |B
5|2015|TV |C
这是我想要的...
如果我在 SQLite 3.28 (Android 11) 或更高版本中 运行 使用相同的命令,我会得到
1|2005|TV |A
2|2005|TV-CD|B
3|2005|CD |B
这里有一个 table 的快速示例,如果您想自己尝试一下
CREATE TABLE 'myTable' ('_id' integer PRIMARY KEY ,'year' NUMERIC ,'command' TEXT, 'code' TEXT);
INSERT INTO myTable VALUES ("1","2005","TV","A");
INSERT INTO myTable VALUES ("2","2005","TV-CD","B");
INSERT INTO myTable VALUES ("3","2005","CD","B");
INSERT INTO myTable VALUES ("4","2010","TV","B");
INSERT INTO myTable VALUES ("5","2015","TV","C");
SELECT * FROM myTable GROUP BY command ORDER BY _id
https://www.jdoodle.com/execute-sql-online/ 对测试很有用,因为它允许您即时更改 SQLite 版本。
我找到了一个解决方案并且可以确认它在两个版本的 SQLite 中都有效
SELECT _id,MAX (year),command,code FROM myTable GROUP BY command ORDER BY _id
正如我在评论中提到的,查询的结果如下:
SELECT * FROM myTable GROUP BY command
是 unpredictable,因为 GROUP BY
应该只用于聚合,比如:
SELECT command, MAX(year) AS max_year
FROM myTable
GROUP BY command
这将 return 每个 command
的最大值 year
。
因此,如果 GROUP BY
和 SELECT * ...
的行为在较新版本中发生了变化,如果您没有使用此类查询,则应该不是问题。
根据我在你的问题中读到的内容,你期望每个 command
行的结果中最大 id
.
在标准 sql 中并且没有 window 函数,大多数版本的 android SQLite 仍然不支持这些函数,您可以先聚合然后加入 table.
但是,SQLite 有一个 documented feature 可供使用,因此您可以使用 裸 列。
这是有效的:
SELECT MAX(_id) AS _id, year, command, code
FROM myTable
GROUP BY command
ORDER BY _id
对于每个 command
.
_id
的行