【问题标题】:MYSQL: GROUP BY with ORDER BY / last post_timeMYSQL:GROUP BY 与 ORDER BY / 最后 post_time
【发布时间】:2023-01-17 22:13:01
【问题描述】:

我有一个主题的作者列表。该列表显示作者姓名和该主题内的最后发布时间。

会员也可以在主题中更频繁地写作。因此,在 poster_id 上设置了“group by”。

整个列表应根据写入日期排序。最新的优先。所以我放置了 maxtime DESC。

问题:

列表输出工作得很好,但作者最后一篇文章的日期不是最后一个 post_time,而是第一个 post_time。

桌子 ”用户“:

user_id username
1 Marc
2 Paul
3 Sofie
4 Julia

桌子 ”帖子

post_id topic_id poster_id post_time
4565 6 1 999092051
4567 6 4 999094056
4333 6 2 999098058
7644 6 1 999090055

这是我的查询:

SELECT 
    p.poster_id, 
    p.post_time, 
    p.post_id,   
    Max(p.post_time) AS maxtime, 
    u.user_id, 
    u.username,
FROM POSTS as p 
INNER JOIN USERS as u ON u.user_id = p.poster_id 
WHERE p.topic_id = 6 
GROUP BY p.poster_id 
ORDER BY maxtime DESC

如何显示 poster_id 的最后一个 post_time 而不是第一个。

非常感谢你。

【问题讨论】:

  • post_time column 是什么数据类型?如果启用了 sql_mode only_full_group_by(顺便说一句应该启用),您的查询将无效
  • post_time 是 int(11)。我想我需要在查询中进行第二个查询以获取 poster_id 的最新 post_time,但我不知道如何连接它。
  • 预期结果应该是什么?
  • 在每行中为每个 poster_id 显示最后一个 post_time 而不是第一个 post_time。你明白吗?非常感谢您的宝贵时间。
  • 这对我来说还不够清楚。您应该在问题中以文本格式添加预期结果。你可以试试this example

标签: sql group-by mariadb


【解决方案1】:

Select 中使用不在分组依据中的列在大多数 qbs 中是被禁止的,因为没有定义显示哪些值。

您可以使用带有 group byhaving 的子查询

SELECT 
    p.poster_id, 
    p.post_time, 
    p.post_id,   
    p.post_time,
    u.user_id, 
    u.username                
FROM posts as p 
INNER JOIN users as u ON u.user_id = p.poster_id 
where (p.poster_id, p.post_time )in(select poster_id, max(post_time) from posts group by poster_id ,p.post_time )

Demo

【讨论】:

  • 非常感谢您的宝贵时间。我将在接下来的几分钟内对此进行测试。我是这么认为的,我需要第二个查询,但我不知道如何...brb。
  • 正如您已经指出的@Jens在 Select 中使用不在 group by 中的列在大多数 qbs 中是被禁止的,因为没有定义显示哪些值你不应该给出一个会失败的答案这与 sql_mode=only_full_group_by 不兼容. dbfiddle.uk/3lZazU49
  • @ErgestBasha 感谢提示。已经监督并现在改变了我的答案
  • 我尝试了这个查询,但是我们的 SQL 由于循环而消失了,所以我不得不重新启动 hole 服务器。我很乐意花你们一杯咖啡或通过贝宝捐款。怎么可能联系到你,解决这个问题?
  • @Jens 在您的查询中缺少 topic_id,我必须在哪里添加它?
【解决方案2】:

您查询的问题是所有非聚合字段都必须出现在 GROUP BY 子句中。只要不满足此条件,您就会遇到 DBMS 引发的错误,或者会出现一些细微的输出错误。此外,由于 SELECT 子句中最后一个选定字段后的逗号,您的查询会引发语法错误。

如果您使用的是 MySQL 8.0,则可以使用 ROW_NUMBER 窗口函数为每个海报选择您的最后发布时间(rownum = 1,按海报分区,按 post_time desc 排序),然后返回到您的 users 表以获取信息。

WITH topic_id6 AS (
    SELECT poster_id, post_time, post_id, 
           ROW_NUMBER() OVER(PARTITION BY poster_id ORDER BY post_time DESC) AS rn 
    FROM POSTS
    WHERE topic_id = 6 
)
SELECT id6.poster_id, id6.post_time, id6.post_id, u.*
FROM       topic_id6 id6 
INNER JOIN USERS     u
        ON id6.poster_id = u.user_id
       AND id6.rn = 1

查看演示 here

【讨论】:

  • 非常感谢您的宝贵时间。我使用玛丽亚数据库。这也可能吗?
  • 是的,这个解决方案也适用于 MariaDB。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-09
  • 2014-08-31
  • 1970-01-01
  • 2011-06-28
  • 1970-01-01
  • 2017-02-11
相关资源
最近更新 更多