【问题标题】:How to select a column value that corresponds to a row returned by a MySQL aggregate function?如何选择与 MySQL 聚合函数返回的行对应的列值?
【发布时间】:2010-06-23 09:14:32
【问题描述】:

我有一张这样的桌子

      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(date) 在同一行中的值。如果每个日期有多个页面浏览量,我可以选择 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 最后 不到一天前访问过,所以他们 被忽略。
  • user_id 3 上次访问 一天前,以及他们最近的 page_id 为 1。

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

谢谢。

【问题讨论】:

    标签: mysql aggregate


    【解决方案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)
    

    【讨论】:

    • 我不知道是否可以同时为同一个 user_id 拥有多个 page_id。如果是,您可能需要将 group by 添加到此查询中
    • 这太好了,谢谢。我不知道你可以加入多个列,而且我忘记了 EXIST 关键字。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-07-31
    • 2021-12-09
    • 1970-01-01
    相关资源
    最近更新 更多