SQLite min / max奇怪的行为

时间:2012-02-01 21:02:35

标签: sqlite aggregate-functions max min

我有一个排名表,其架构被定义为rank(id,key,value),其中key是主键

sqlite> .schema rank
CREATE TABLE 'rank' ( ID VARCHAR, KEY VARCHAR, VALUE VARCHAR NOT NULL );
CREATE INDEX 'rank_id___djklaf3451jlZZZRFfa___' ON 'rank' ( ID );

sqlite> select * from rank;
-----------------------------------------------------
Tymb-W64uwvM|Tymc8LPQnxBg|5
TymdPRdFpBcE|TymdSsaIFhuI|2
TymdPRdFpBcE|TymdjkGgExcE|3
TymeVf6N1RH4|TymeZGxydCJ8|3
TymeVf6N1RH4|Tymeecz1ORW8|20

sqlite> select id,min(value) from rank group by id;
------------------------------------------------------
Tymb-W64uwvM|5
TymdPRdFpBcE|2
TymeVf6N1RH4|20

sqlite> select id,max(value) from rank group by id;
------------------------------------------------------
Tymb-W64uwvM|5
TymdPRdFpBcE|3
TymeVf6N1RH4|3

正如您所看到的,最小和最大功能的第3个结果都不正确。 sqlite版本是3.6.23。

有什么建议吗?

2 个答案:

答案 0 :(得分:5)

这是因为value是一种字符类型(特别是varchar)而不是数字类型。

如果您要对字符数据进行排序,则会显示为:

2
20
3
3
5

如果你执行了,那就是你所看到的:

select value from rank order by value asc

如果要对其进行数字排序,则应将列定义为数字类型,例如integer

答案 1 :(得分:3)

这是因为您输入了第3个参数VARCHAR。答案是“正确的”,因为它是VARCHAR排序。如果你输入了第三个参数INTEGER,你可能会更喜欢结果。即你的CREATE TABLE语句应该是:

CREATE TABLE 'rank' ( ID VARCHAR, KEY VARCHAR, VALUE INTEGER NOT NULL );

否则,如果VALUE必须保持为VARCHAR,你应该尝试使用以下select语句来动态投射,但正如其他人所说,这对于性能来说并不是很好:

SELECT ID, MIN(CAST(VALUE AS INTEGER)) FROM RANK GROUP BY ID;