Подтвердить что ты не робот

GROUP BY с датой MAX

У меня проблема при выполнении этого кода:

SELECT * FROM tblpm n 
WHERE date_updated=(SELECT MAX(date_updated) 
FROM tblpm GROUP BY control_number 
HAVING control_number=n.control_number)

В принципе, я хочу вернуть самую последнюю дату для каждого контрольного номера. Вышеуказанный запрос возвращает правильный результат, но он занимает 37 секунд. до того, как был показан выход.

Есть ли какое-либо другое предложение или команда sql, которые могут выполняться быстрее, чем запрос выше?

Спасибо заранее.

4b9b3361

Ответ 1

Помещение подзапроса в предложение WHERE и ограничение его на n.control_number означает, что он выполняет подзапрос много раз. Это называется коррелированным подзапросом, и он часто является убийцей производительности.

Лучше запустить подзапрос один раз в предложении FROM, чтобы получить максимальную дату на контрольный номер.

SELECT n.* 
FROM tblpm n 
INNER JOIN (
  SELECT control_number, MAX(date_updated) AS date_updated
  FROM tblpm GROUP BY control_number
) AS max USING (control_number, date_updated);

Ответ 2

В этом подзапросе нет необходимости группировать... предложение where должно быть достаточным:

SELECT * FROM tblpm n
WHERE date_updated=(SELECT MAX(date_updated)
    FROM tblpm WHERE control_number=n.control_number)

Кроме того, есть ли указатель в столбце 'date_updated'? Это, безусловно, поможет.

Ответ 3

Другой способ, который не использует группу:

SELECT * FROM tblpm n 
  WHERE date_updated=(SELECT date_updated FROM tblpm n 
                        ORDER BY date_updated desc LIMIT 1)

Ответ 4

Быстро и просто с HAVING:

SELECT * FROM tblpm n 
FROM tblpm GROUP BY control_number 
HAVING date_updated=MAX(date_updated);

В контексте HAVING, MAX находит максимум каждой группы. Только последняя запись в каждой группе будет удовлетворять date_updated=max(date_updated). Если есть связь для последней в группе, оба передают фильтр HAVING, но GROUP BY означает, что в возвращенной таблице будет отображаться только один.