Получение неправильных значений для других столбцов, когда я выбираю MAX (updated_date) - PullRequest
3 голосов
/ 11 марта 2012

Я использую select field1, max(updated_date) from mytable.
Я получаю правильное значение для max(updated_date), то есть наибольшую дату.
Однако для field1 Я просто получаю значение для первой записи, то есть "ta1"когда я действительно хочу значение" ta3 "из третьей записи (с максимальным значением даты).

например

+------------+---------------------+
| field1     | update_date         |
+------------+---------------------+
| ta1        | 2012-03-11 11:05:15 |
| ta2        | 2012-03-11 11:05:32 |
| ta3        | 2012-03-11 11:05:56 |
+------------+---------------------+
3 rows in set (0.00 sec)

+------------+---------------------+
| field1     | max(update_date)    |
+------------+---------------------+
| ta1        | 2012-03-11 11:05:56 |
+------------+---------------------+
1 row in set (0.00 sec)

Ответы [ 2 ]

5 голосов
/ 11 марта 2012

Вам нужно предложение GROUP BY или более сложный запрос.

SELECT field1, MAX(updated_date)
  FROM mytable
 GROUP BY field1

Для данных примера будет возвращено 3 строки.

Скорее всего, вы хотите:

SELECT t1.field1, t3.max_date
  FROM mytable AS t1
  JOIN (SELECT MAX(t2.updated_date) AS max_date
          FROM mytable AS t2
       ) AS t3
    ON t1.updated_date = t3.max_date;

Для данных примера будет возвращаться 1 строка:

ta3   2012-03-11 11:05:56

Из основных СУБД только MySQL позволяет опускать предложение GROUP BY, когда в списке выбора есть смесь агрегированных и неагрегированных столбцов. Стандарт SQL требует предложения GROUP BY, и вы должны перечислить в нем все неагрегированные столбцы. Иногда в MySQL пропуск предложения GROUP BY приводит к желаемому ответу; однако часто ему удается дать неожиданный ответ.

3 голосов
/ 11 марта 2012

Используйте ORDER BY и LIMIT.
Тогда это просто:

  SELECT field1, updated_date 
    FROM mytable
ORDER BY updated_date DESC 
   LIMIT 1;

Если запрос много нужен, вы можете попробовать эту альтернативу:

  SELECT t1.field1, t1.updated_date 
    FROM mytable t1
         LEFT JOIN mytable t2 
     AND t2.updated_date > t1.updated_date
   WHERE t2.field1 IS NULL;

Краткое объяснение:
Для каждой строки, дайте мне любые строки с более свежим updated_date.
Но (предложение WHERE) возьмите только строку с более новым updated_date.
Этот метод иногда называется самоисключающим соединением.
Это промежуточный результат (без предложения WHERE и добавления t2.* в список SELECT):

ta1    2012-03-11 11:05:15    ta2     2012-03-11 11:05:32
ta1    2012-03-11 11:05:15    ta3     2012-03-11 11:05:56
ta2    2012-03-11 11:05:32    ta3     2012-03-11 11:05:56
ta3    2012-03-11 11:05:56    null    null
...