MySQL выбирает MAX (datetime), не возвращая максимальное значение

Пример таблицы:

id   computer  app      version     build    date
---|---------|------|------------|-------|---------
1  |  aaaa1  | app1 |   1.0.0    |   1   | 2013-11-11 09:51:07
2  |  aaaa1  | app2 |   2.0.0    |   2   | 2013-11-12 09:51:07
5  |  xxxx2  | app1 |   1.0.0    |   1   | 2013-11-13 09:51:07
3  |  cccc3  | app2 |   3.1.0    |   1   | 2013-11-14 09:51:07
4  |  xxxx2  | app1 |   1.0.0    |   2   | 2013-11-15 09:51:07
5  |  cccc3  | app2 |   3.1.1    |   3   | 2013-11-16 09:51:07
6  |  xxxx2  | app1 |   1.0.2    |   1   | 2013-11-17 09:51:07
7  |  aaaa1  | app1 |   1.0.2    |   3   | 2013-11-18 09:51:07

Желаемый вывод (неточный формат или порядок листинга), получение последней установки для каждого приложения на каждом компьютере:

7. aaaa1 - app1 - 1.0.2 - 3 - 2013-11-18 09:51:07
2. aaaa1 - app2 - 2.0.0 - 2 - 2013-11-12 09:51:07
6. xxxx2 - app1 - 1.0.2 - 1 - 2013-11-17 09:51:07
5. cccc3 - app2 - 3.1.1 - 3 - 2013-11-16 09:51:07

Мой оператор SQL:

SELECT 
        id,
        computer, 
        app, 
        version, 
        build, 
        MAX(date) AS installed
    FROM 
        data 
    WHERE 
        placement = 'xxx'
    GROUP BY 
        app, computer
    ;

Это дает мне:

1. aaaa1 - app1 - 1.0.0 - 1 - 2013-11-11 09:51:07

а не

7. aaaa1 - app1 - 1.0.2 - 3 - 2013-11-18 09:51:07

как я и ожидал.

MAX (дата) работает, если я ТОЛЬКО выберите MAX (дата) и ничего больше. Но тогда я не получаю никаких данных для работы (только последняя дата).

SELECT 
        MAX(date) AS installed

Я не ниндзя SQL, поэтому я скоро пойду лысым, почесывая голову из-за этого.

Ответ 1

Попробуйте вот так:

SELECT d.id, d.computer, d.app, d.version, d.build, a.installed
FROM data d
INNER JOIN (
  SELECT computer, app, max(DATE) AS installed
  FROM data
  GROUP BY computer, app
  ) a ON a.computer = d.computer AND a.app = d.app
WHERE placement = 'xxx'

Внутренний запрос получает максимальную (дату) для каждой пары компьютеров и приложений, затем вы просто присоединяетесь к этому, чтобы получить остальную информацию.

Ответ 2

Попробуйте ввести поле Datetime

 SELECT 
            id,
            computer, 
            app, 
            version, 
            build, 
            MAX(cast(date as Datetime)) AS installed
        FROM 
            data 
        WHERE 
            placement = 'xxx'
        GROUP BY 
           app, computer, id, version, build
        ;

Ответ 3

max - это агрегатная функция, которая пытается добавить все столбцы из оператора select в GROUP BY:

GROUP BY 
    app, computer, id, version, build.

Ответ 4

Возможно, это потому, что вы храните дату как String, а сравнение строки действует иначе, чем сравнение целого числа. Вы должны сохранить свою дату в формате unix Timestamp, и их будет намного проще сравнивать. Но вам потребуется дополнительное усилие, которое будет отображаться как обычная английская дата.

Ответ 5

Что случилось с:

SELECT 
    id,
    computer, 
    app, 
    version, 
    build, 
    `date` AS installed
FROM 
    data 
WHERE 
    placement = 'xxx'
ORDER BY installed DESC
GROUP BY app;

Ответ 6

У меня не работал MAX, работал дополнительный подзапрос, где я предварительно упорядочивал таблицу по дате:

SELECT d.id, d.computer, d.app, d.version, d.build, a.installed
FROM data d
INNER JOIN (
  SELECT computer, app, date as installed
  FROM (
    SELECT computer, app, date
    FROM data
    ORDER BY date desc
  ) as t
  GROUP BY computer, app
  ) a ON a.computer = d.computer AND a.app = d.app
WHERE placement = 'xxx'