MySQL ORDER BY игнорируется с помощью GROUP BY (Эффективное решение?) - PullRequest
2 голосов
/ 24 февраля 2011

Я чувствую, что есть простое решение - я смотрел на другие вопросы о переполнении стека, но они кажутся неэффективными, или, возможно, я делаю их неправильно.

Вот упрощенные версии таблиц, с которыми я работаю.

CREATE TABLE object_values (
  object_value_id INT PRIMARY KEY,
  object_id INT,
  value FLOAT,
  date_time DATETIME,
  INDEX (object_id)
);

CREATE TABLE object_relations (
  object_group_id INT,
  object_id INT,
  INDEX (object_group_id, object_id)
);

Существует отношение многие-к-одному - множество значений объекта на один объект (в среднем 150 значений объекта на объект)

Я хочу получить последнее значение объекта (определяемое полем date_time) для каждого object_id на основе object_group_id.

Текущий запрос:

SELECT a.`object_id`, a.`value` 
FROM `object_values` AS a 
    LEFT JOIN `object_relations` AS b 
        ON ( a.`object_id` = b.`object_id` ) 
WHERE b.`object_group_id` = 105 
ORDER BY a.`date_time` DESC

Это возвращает все записи - если я выполняю GROUP BY a. object_id, тогда ORDER BY игнорируется

Я пробовал серию вариантов - и я прошу прощения, потому что знаю, что это распространенный вопрос, но попытка других решений пока не совсем работает. Любая помощь будет принята с благодарностью.

Некоторые решения вернулись с результатами примерно через 70 секунд - это большая система, поэтому она должна быть немного быстрее.

Ответы [ 2 ]

2 голосов
/ 24 февраля 2011
SELECT a.object_id, a.`value`
FROM object_values a JOIN object_relations b
    ON a.object_id = b.object_id
    JOIN (
    SELECT a.object_id, MAX(a.date_time) MaxTime
    FROM object_relations b JOIN object_values a
        ON a.object_id = b.object_id
    WHERE b.`object_group_id` = 105 
    GROUP BY a.object_id
  ) g ON a.object_id = g.object_id AND a.date_time = g.MaxTime
WHERE b.`object_group_id` = 105 
GROUP BY a.object_id

Вы можете опустить окончательный GROUP BY, если в одной группе никогда не будет дубликата date_time.

1 голос
/ 24 февраля 2011

Попробуйте эту версию без группы, используя подзапрос, чтобы получить максимальную дату для каждого объекта:

SELECT a.`object_id`, a.`value` 
FROM `object_relations` b 
JOIN `object_values` a 
 ON b.`object_id` = a.`object_id`
 AND b.`object_group_id` = 105
WHERE a.`date_time` = (select MAX(date_time) from object_values where object_id = a.object_id)

В левом соединении не было необходимости, поскольку вы указали идентификатор группы в предложении where,поэтому я сделал группу главной таблицей в соединении.Это можно сделать несколькими способами.Подзапрос также может быть перемещен в предложение join, если WHERE только что изменено на AND.

...