Как получить несколько максимальных значений столбца для нескольких строк с одинаковым идентификатором? - PullRequest
0 голосов
/ 25 января 2019

Мне нужно выбрать максимальные суммы в одном столбце для общего идентификатора в другом столбце. В столбце report_id может быть несколько идентификаторов с одинаковыми максимальными значениями last_update.

Структура данных:

+------+-------+--------------------------------------------+
| id   | report_id   | last_update                          |
+------+-------------+--------------------------------------+
| 1    | 1           | 2019-01-24                           |
| 2    | 1           | 2019-01-24                           |
| 3    | 1           | 2019-01-24                           |
| 4    | 2           | 2019-01-24                           |
| 5    | 3           | 2019-01-23                           |
+------+-------+--------------------------------------------+

Проблема, с которой я столкнулся до сих пор, заключается в том, что я не могу изолировать свои результаты просто с помощью report_id. Например, с помощью следующего запроса:

"SELECT report_id, last_update
 FROM reports
 WHERE last_update=(
               SELECT MAX(last_update) FROM reports 
               WHERE report_id='1'
               );  
            ";

Возвращает:

+------+-------+--------------------------------------------+
| id   | report_id   | last_update                          |
+------+-------------+--------------------------------------+
| 1    | 1           | 2019-01-24                           |
| 2    | 1           | 2019-01-24                           |
| 3    | 1           | 2019-01-24                           |
| 4    | 2           | 2019-01-24                           |
+------+-------+--------------------------------------------+ 

Так что это почти правильно, но оно также включает report_id 2, потому что оно также имеет значение MAX 2019-01-24 в last_update.

Что мне действительно нужно сделать, это выбрать все столбцы с параметром report_id, равным 1, а затем выбрать только строки из этого набора результатов с MAX (last_update), но я просматривал каждый наибольший n-й на группу и связанный вопрос на ТАК, и я просто не могу получить это.

Каждый раз, когда я добавляю MAX в запрос, это, кажется, сводит на нет тот факт, что я пытаюсь изолировать и report_id.

1 Ответ

0 голосов
/ 25 января 2019

Вот несколько решений:

Сравнение кортежей:

SELECT report_id, last_update
 FROM reports
 WHERE (report_id, last_update) = (
               SELECT report_id, MAX(last_update) FROM reports 
               WHERE report_id='1'
               GROUP BY report_id
               );

Сравнение кортежей с производной таблицей вместо зависимого подзапроса:

SELECT report_id, last_update
 FROM reports
 INNER JOIN (
   SELECT report_id, MAX(last_update) AS last_update
   FROM reports WHERE report_id='1' GROUP BY report_id
 ) USING (report_id, last_update);

Решение без подзапросов, использующее исключающее соединение, чтобы найти отчеты, для которых нет других отчетов с таким же идентификатором report_id и большей датой обновления:

SELECT r1.*
FROM reports AS r1
LEFT OUTER JOIN reports AS r2
  ON r1.report_id=r2.report_id AND r1.last_update<r2.last_update
WHERE r2.report_id IS NULL;

Решение MySQL 8.0 с оконными функциями:

WITH ranked_reports AS (
  SELECT r.*, DENSE_RANK() OVER (PARTITION BY report_id ORDER BY last_update DESC) AS dr
  FROM reports WHERE report_id='1'
)
SELECT * FROM ranked_reports WHERE dr=1;
...