2011-01-28 1 views
13

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

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 

Я хочу, чтобы сделать запрос, который возвращает строки, соответствующие каждой странице смотреть на каждый user WITH THE CATCH. Если пользователь просматривал страницу более одного раза, я получаю строку, соответствующую последнему виду (т. е. наибольшее значение TIME). Таким образом, я должен получить это:

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 и встроенными запросами, а затем мой мозг взрывается. Какие-либо предложения? Благодаря!

+0

Дубликат вопрос [HTTP: // stackoverflow.com/questions/612231/how-can-i-select-rows-with-maxcolumn-value-distinct-by-another-column-in-sql] – user1486030

ответ

19

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

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 

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

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

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

SELECT MAX(time) as time, user, page_id 
    FROM TableName 
GROUP BY user, page_id 
ORDER BY time DESC 
+0

Да, это правильно. Огромное спасибо! Вероятно, я должен был упомянуть, что мне нужно поле NID; Я попал к вашему второму, NID-менее примеру, но этого, как отмечено, недостаточно. Разметка вашего ответа и подтверждение его, как ответ будет следовать; Я также даю себе пять баллов за то, что правильно понял, что я никогда бы не справился с этим сам ... –

1

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

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
SELECT nid, MAX(time), user, page_id 
FROM TableName 
GROUP BY nid, user, page_id 
Смежные вопросы