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, которые могут выполняться быстрее, чем запрос выше?
Спасибо заранее.
Ответы
Ответ 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
означает, что в возвращенной таблице будет отображаться только один.