Как выбрать строки из MySQL на основе максимального значения столбца + группировка - PullRequest
14 голосов
/ 28 января 2011

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

nid     time    user  page_id
 25     8000       4      467
 24     7000       1      482
 23     6000       1      484
 22     5000       1      482
 21     4000       5      467
 20     3000       4      467

Я хочу сделать запрос, который возвращает строки, соответствующие каждой просмотренной странице.каждым пользователем С ЛОВОМ, ЧТО, если пользователь просматривал страницу более одного раза, я получаю строку, соответствующую самому последнему виду (т. е. наибольшему значению ВРЕМЕНИ).Таким образом, я должен получить это:

nid     time    user  page_id
 25     8000       4      467
 24     7000       1      482
 23     6000       1      484
 21     4000       5      467

Мы теряем строку 22, потому что пользователь 1 посмотрел на страницу 482 позже, и мы теряем строку 20, потому что пользователь 4 посмотрел страницу 467 позже.

Я почти понял это, но я не могу его взломать, и при этом убедить себя, что полученные результаты будут в целом правильными, а не просто случайностью моих тестовых случаев.Я продолжаю идти вперед и назад между запросами GROUP BY или DISTINCT и встроенными запросами, и затем мой мозг взрывается.Какие-либо предложения?Спасибо!

Ответы [ 3 ]

20 голосов
/ 28 января 2011

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

SELECT fullTable.nid as nid, 
       recent.time as time, 
       fullTable.user as user, 
       fullTable.page_id as page_id 
  FROM TableName fullTable 
         INNER JOIN   (SELECT MAX(t1.time) as time, t1.user, t1.page_id 
                         FROM TableName t1 
                     GROUP BY user, page_id) recent
                 ON recent.time = fullTable.time AND 
                    recent.user = fullTable.user AND 
                    recent.page_id = fullTable.page_id
ORDER BY time DESC

Если вы запрашиваете столбец за пределами предложения group by, mysql может вернуть любое значение для этого столбца внутри этой группы.Поэтому, если все значения внутри группы не совпадают, то есть ваш случай, вы не можете включить его непосредственно в предложение select, вам нужно использовать объединение.

Вы можете прочитать больше о несгруппированныхстолбцы на MySQL на ссылка

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

SELECT MAX(time) as time, user, page_id 
  FROM TableName
GROUP BY user, page_id
ORDER BY time DESC
1 голос
/ 28 января 2011

Попробуйте это:

SELECT *
  FROM <YOUR_TABLE>
 WHERE (user, page_id, time) IN
    (
    SELECT  user, page_id, MAX(time) time
      FROM <YOUR_TABLE>
    GROUP BY user, page_id
   )
0 голосов
/ 28 января 2011
SELECT nid, MAX(time), user, page_id 
FROM TableName 
GROUP BY nid, user, page_id
...