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

发布于 2024-10-14 19:34:15 字数 776 浏览 6 评论 0原文

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

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 查询和嵌入式查询之间来回切换,然后我的大脑就爆炸了。有什么建议吗?谢谢!

I've got a table that contains (let's say) all the times when a user looked at a specific webpage. Users can of course look at a page more than once, so there can be multiple entries for users and pages, like so:

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

I want to do a query that returns the rows corresponding to every page viewed by every user WITH THE CATCH THAT if a user looked at a page more than once, I get the row corresponding to the most recent view (i.e., the largest value of TIME). Thus, I should get this:

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

We lose row 22 because user 1 looked at page 482 at a later time, and we lose row 20 because user 4 looked at page 467 at a later time.

I almost have this figured out, but I can't quite crack it, while also convincing myself that the results I'm getting will be generally correct and not just an accident of my test cases. I keep going back and forth between GROUP BY or DISTINCT queries and embedded queries, and then my brain explodes. Any suggestions? Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

此岸叶落 2024-10-21 19:34:15

如果你需要完整的行,你可以使用这个:

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

If you need the full row you can use this:

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

If you ask for a column outside the "group by" clause, mysql can return any value for this column inside this group. So if all the values inside the group are not the same, that is your case, you can't include it directly on the select clause, you need to use a join.

You can read more about not grouped columns on MySQL on the reference

If you don't need the nid field, you can use this other:

SELECT MAX(time) as time, user, page_id 
  FROM TableName
GROUP BY user, page_id
ORDER BY time DESC
秋心╮凉 2024-10-21 19:34:15

试试这个:

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
   )

Try this:

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
   )
隐诗 2024-10-21 19:34:15
SELECT nid, MAX(time), user, page_id 
FROM TableName 
GROUP BY nid, user, page_id
SELECT nid, MAX(time), user, page_id 
FROM TableName 
GROUP BY nid, user, page_id
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文