ORDER BY Подзапрос для преобразования GROUP BY в JOIN - PullRequest
1 голос
/ 19 августа 2011

у меня есть эта таблица

id |   title   | amount | timestamp
1  |  random1  |   150  | 1313635011
2  |  random2  |   190  | 1313635730
3  |  random2  |   210  | 1313637359
4  |  random2  |   100  | 1313691807
5  |  random3  |   130  | 1313692673
6  |  random4  |   900  | 1313692739
7  |  random4  |   111  | 1313692988

я хочу получить этот результат (строки с разными заголовками и самыми большими метками времени):

id |   title   | amount | timestamp
1  |  random1  |   150  | 1313635011
4  |  random2  |   100  | 1313691807
5  |  random3  |   130  | 1313692673
7  |  random4  |   111  | 1313692988

У меня есть этот запрос.

SELECT * FROM (
  SELECT * FROM table ORDER BY timestamp DESC 
) m GROUP BY title

Это работает как шарм, но можно ли это преобразовать в оператор JOIN?

Спасибо

Ответы [ 2 ]

3 голосов
/ 19 августа 2011

Это можно упростить до следующего (ORDER BY в подзапросе бесполезен):

SELECT * 
FROM table
GROUP BY title

Почему вы думаете, что вам нужно JOIN?(Хорошо, это было решено с помощью комментариев).


После вашего комментария, который вам нужен для каждого заголовка, строки с наибольшей отметкой времени, это сделает работу:

SELECT t.* 
FROM
    table AS t
  JOIN
    ( SELECT title
           , MAX(timestamp) AS maxts
      FROM table
      GROUP BY title
    ) AS grp
    ON grp.title = t.title
    AND grp.maxts = t.timestamp
ORDER BY t.timestamp DESC

Для записи, ваш исходный запрос:

SELECT * 
FROM 
  ( SELECT * 
    FROM table 
    ORDER BY timestamp DESC 
  ) m
GROUP BY title

может работать должным образом, но: только в MySQL, что позволяет использовать в SELECT список полей, которые не входят в предложение GROUP BY (или зависят от них), без каких-либо агрегатных функций в них.Таким образом, приведенный выше запрос будет возвращать более или менее случайную строку для каждого заголовка.Фактически, он вернет первую строку, которую найдет для заголовка.Таким образом, первый запуск подзапроса (который упорядочивает по timestamp DESC) приводит к нахождению первой строки с наибольшей отметкой времени.

Однако это происходит только потому, что (когда, если) оптимизатор не понимает, что подзапросбесполезно.Вы можете обнаружить, что ваш оригинальный запрос работает нормально, когда однажды вы обновляетесь до MySQL версии 7.5 и ваш запрос перестает работать, как раньше.(потому что оптимизатор стал более умным и преобразовал ваш запрос в более простой без подвыбора).

Вы можете даже обнаружить, что ваш запрос вообще перестал работать и выдает ошибку, если MySQL решит, что в будущем выпуске будут условиясо стандартами SQL для запросов GROUP BY.

0 голосов
/ 19 августа 2011

Неверный оператор sql.

Недопустимый ORDER BY в подзапросе

GROUP BY требуется агрегатная функция, например COUNT, SUM и т. Д.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...