Если столбец в предложении SELECT не указан в предложении GROUP BY, группа SQLite по остальным столбцам (по умолчанию), а затем возвращает значение опущенного столбца в первой строке, которую он оценивает ?поведение группы SQLite
Например, найти TransactionID, связанный с наивысшим значением за ProductID:
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;
Running предыдущие заявления дает мне TransactionType из 7 для PRODUCTID 1 (максимальное значение 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);
Он теперь будет возвращать TransactionType 10 для PRODUCTID 1.
Является ли это поведение конструкции, или это просто ненадежный побочный эффект?
EDIT: Кажется, что это ненадежный побочный эффект. Из документации:
Каждое выражение в результирующем наборе затем оценивается один раз для каждой группы строк . Если выражение является агрегированным выражением, оно равно , которое оценивается по всем строкам в группе. В противном случае оценивается против одной произвольно выбранной строки из группы. Если существует более одного неагрегатного выражения в результирующем наборе, , тогда все такие выражения оцениваются для одной и той же строки.
https://www.sqlite.org/lang_select.html#resultset
'TransactionType' не является ни частью' GROUP BY', ни использоваться в агрегатной функции, поэтому какая строка SQLite использует для результат «TransactionType» не указан. –