如何根据列+分组的最大值从MySQL中选择行

时间:2011-01-28 17:59:53

标签: sql mysql group-by distinct

当用户查看特定网页时,我有一个包含(假设)的表格。用户当然可以多次查看页面,因此用户和页面可以有多个条目,如下所示:

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

我想做一个查询,返回与每个用户查看的每个页面对应的行。如果用户多次查看某个页面,我会得到与最新视图相对应的行(即, 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查询和嵌入式查询之间来回切换,然后我的大脑爆炸了。有什么建议?谢谢!

3 个答案:

答案 0 :(得分:20)

如果您需要整行,可以使用:

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子句中,您需要使用连接。

您可以在the reference

上阅读有关MySQL未分组列的更多信息

如果您不需要nid字段,则可以使用另一个字段:

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

答案 1 :(得分: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
   )

答案 2 :(得分:0)

SELECT nid, MAX(time), user, page_id 
FROM TableName 
GROUP BY nid, user, page_id