SQLite行为群

SQLite行为群,sqlite,group-by,Sqlite,Group By,如果从GROUPBY子句中省略SELECT子句中的一列,SQLite是否按其余列进行分组(默认情况下),然后在其计算的第一行中返回省略列的值 例如,查找与每个ProductId的最高值关联的TransactionId: CREATE TABLE IF NOT EXISTS ProductTransaction ( Id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, ProductId INTEGER NOT NULL, Transact

如果从GROUPBY子句中省略SELECT子句中的一列,SQLite是否按其余列进行分组(默认情况下),然后在其计算的第一行中返回省略列的值

例如,查找与每个ProductId的最高值关联的TransactionId:

CREATE TABLE IF NOT EXISTS ProductTransaction
(
   Id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
   ProductId INTEGER NOT NULL,
   TransactionType INTEGER NOT NULL,
   Value INTEGER NOT NULL
);

INSERT INTO ProductTransaction (ProductId, TransactionType, Value)
VALUES (1, 7, 23), (1, 3, 12), (2, 4, 43), (1, 7, 5), (1, 10, 23), 
(3, 3, 23), (3, 2, 31), (1, 1, 23), (2, 5, 50),  (2, 6, 14), (1, 4, 23);

SELECT ProductId
, TransactionType
, MAX(Value)
FROM ProductTransaction
GROUP BY ProductId;

DELETE FROM ProductTransaction;
运行前面的语句可以得到ProductID1的TransactionType为7(最高值23)

但是,如果我在索引中添加了一个

CREATE INDEX IF NOT EXISTS IDX_TransType ON ProductTransaction(ProductId ASC, TransactionType ASC);
它返回TransactionType 1,可能是因为它现在根据索引对行进行排序。修改索引支持这一理论:

CREATE INDEX IF NOT EXISTS IDX_TransType ON ProductTransaction(ProductId ASC, TransactionType DESC);
它现在将返回ProductId 1的TransactionType 10

这种行为是故意的,还是仅仅是一种不可靠的副作用

编辑:这似乎是一个不可靠的副作用。从文件中:

然后,对结果集中的每个表达式分别计算一次 一组行。如果表达式是聚合表达式,则为 跨组中的所有行计算否则,将对其进行评估 针对组内任意选择的一行。如果 结果集中有多个非聚合表达式, 然后对同一行计算所有此类表达式


自SQLite 3.7.11以来,使用MAX()或MIN()将强制所有非聚合列来自与MAX()/MIN()匹配的同一行


但是,当有多行具有相同的最大值/最小值时,其他列的值仍不确定来自这些行中的哪一行。(SQLite的行为在这方面是一致的,但可以在不同版本或不同的数据库架构中更改。)

TransactionType
既不属于
GROUP BY
的一部分,也不用于聚合函数,因此SQLite对
TransactionType
结果使用哪一行是未指定的。