Приказ по MySQL проигнорировал с группы (эффективного обойти?)


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

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

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

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

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

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

2 ответа:

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.

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

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, если, где только и.