Основная проблема заключается в том, что SELECT является агрегированным запросом, поскольку он содержит предложение GROUP BY: -
Существует два типа простого оператора SELECT - агрегат и
неагрегированные запросы. Простой оператор SELECT - это совокупный запрос
если он содержит предложение GROUP BY или один или несколько агрегатов
функции в наборе результатов.
SQL как понял SQLite - SELECT
И, таким образом, значение столбца для этой группы будет произвольным значением столбца этой группы (я подозреваю, что сначала согласно сканированию / поиску, отсюда и более низкие значения): -
Если оператор SELECT является агрегированным запросом без GROUP BY
предложение, затем оценивается каждое статистическое выражение в наборе результатов.
один раз по всему набору данных. Каждое неагрегированное выражение в
Набор результатов оценивается один раз для произвольно выбранной строки
набор данных. Одна и та же произвольно выбранная строка используется для каждого
неагрегированное выражение. Или, если набор данных содержит ноль строк, то
каждое неагрегированное выражение оценивается по строке, состоящей из
полностью из значений NULL.
Короче говоря, вы не можете полагаться на значения столбцов, которые не являются частью группы / агрегации, когда это агрегированный запрос.
Поэтому приходится извлекать необходимые значения, используя агрегированное выражение, например, max (app.time). Тем не менее, вы не можете ЗАКАЗАТЬ по этому значению (точно не знаю, почему оно, вероятно, наследуемо в аспекте эффективности)
ОДНАКО
Что вы можете сделать, это использовать запрос для построения CTE, а затем сортировать без использования агрегатов.
Рассмотрим следующее, которое, как мне кажется, имитирует вашу проблему: -
DROP TABLE IF EXISTS users;
DROP TABLE If EXISTS app;
CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY, username TEXT);
INSERT INTO users (username) VALUES ('a'),('b'),('c'),('d');
CREATE TABLE app (the_id INTEGER PRIMARY KEY, id INTEGER, appname TEXT, time TEXT);
INSERT INTO app (id,appname,time) VALUES
(4,'app9',721),(4,'app10',7654),(4,'app11',11),
(3,'app1',1000),(3,'app2',7),
(2,'app3',10),(2,'app4',101),(2,'app5',1),
(1,'app6',15),(1,'app7',7),(1,'app8',212),
(4,'app9',721),(4,'app10',7654),(4,'app11',11),
(3,'app1',1000),(3,'app2',7),
(2,'app3',10),(2,'app4',101),(2,'app5',1),
(1,'app6',15),(1,'app7',7),(1,'app8',212)
;
SELECT * FROM users;
SELECT * FROM app;
SELECT username
,count(app.id)
, max(app.time) AS latest_time
, min(app.time) AS earliest_time
FROM users JOIN app ON users.id = app.id
GROUP BY users.id
ORDER BY max(app.time)
;
В результате: -
Там, где было извлечено последнее время для каждой группы, окончательный результат не был отсортирован, как вы думаете.
Завершение этого в CTE может исправить это, например. : -
WITH cte1 AS
(
SELECT username
,count(app.id)
, max(app.time) AS latest_time
, min(app.time) AS earliest_time
FROM users JOIN app ON users.id = app.id
GROUP BY users.id
)
SELECT * FROM cte1 ORDER BY cast(latest_time AS INTEGER) DESC;
и сейчас: -
- Обратите внимание, что для моего удобства вместо целых чисел были использованы простые целые числа.