如何选择与MySQL聚合函数返回的行对应的列值?

时间:2010-06-23 09:14:32

标签: mysql aggregate

我有一张像

这样的表格
      date               user_id          page_id
2010-06-19 16:00:00         1                4
2010-06-19 16:00:00         3                4
2010-06-20 07:10:00         1                1
2010-06-20 12:00:10         1                2
2010-06-20 12:00:10         1                3
2010-06-20 13:05:00         2                1
2010-06-20 14:10:00         3                1
2010-06-21 17:00:00         2                1         

我想写一个查询,它将返回那些在过去一天没有访问过的用户的最后一个page_id。

所以,我可以找到最后一天没有访问过的人:

SELECT user_id, MAX(page_id) 
FROM page_views GROUP BY user_id 
HAVING MAX(date) < DATE_SUB(NOW(), INTERVAL 1 DAY);

但是,如何找到这些用户上次查看过的page_id?即我想知道哪个page_id对应于与MAX(日期)相同的行中的值。如果每个日期有多个页面查看,我可以选择MAX(page_id)。

上面的预期输出应该是(如果NOW()返回2010-06-21 18:00:00):

user_id      page_id
   1            3
   3            1
  • user_id 1上一次访问过一天前 在2010-06-20 12:00:10,和 MAX(page_id)为3.
  • user_id 2 last 不到一天前访问过,所以他们 被忽略了。
  • user_id 3上次访问过 一天前,和他们最近的 page_id是1。

我怎样才能做到这一点?我只需要使用SQL。我正在使用MySQL派生,要求SELECT子句中的所有列都在GROUP BY子句中声明(它更符合标准)。

感谢。

1 个答案:

答案 0 :(得分:1)

我可以看到不同的方法。 例如:

select a.user_id, a.page_id
from page_views a
inner join (SELECT user_id, MAX(date) as date
FROM page_views GROUP BY user_id 
HAVING MAX(date) < DATE_SUB(NOW(), INTERVAL 1 DAY) ) b on a.user_id = b.user_id 
    and a.date = b.date

可以在带有窗口函数的MS SQL或Oracle中实现更有效。

另一个想法:

select a.user_id, a.page_id
from page_views a
where date < DATE_SUB(NOW(), INTERVAL 1 DAY)
    and not exist(select 1 from page_views b 
        where a.user_id = b.user_id and b.date > a.date)