【问题标题】:How to get the most recent row in group in mysql?如何在mysql中获取组中的最新行?
【发布时间】:2015-02-17 23:57:45
【问题描述】:

在我的 mysql 查询中,我尝试获取所有线程的最新行。

    $query = "SELECT th.id, tm.message, tm.date_sent, tm.date_sent>tu.last_read_date AS new
              FROM thread th
              JOIN thread_user tu ON th.id=tu.thread_id AND tu.user_id={$user_id}
              JOIN thread_message tm ON th.id=tm.thread_id
              JOIN (
                   SELECT thread_id, MAX(date_sent) date_sent
                   FROM thread_message
                   GROUP BY thread_id
              ) q ON tm.thread_id = q.thread_id AND tm.date_sent = q.date_sent
              ORDER BY tm.date_sent DESC";  

这可行,但问题是,如果有两行或多行的日期是最新的并且它们是相同的日期,那么它将与它们一起加入。我需要第三个 join 语句最多加入 1 行。

我也不想假设最大的 id 意味着它的最新行,因为我以后总是可以手动更改日期。

有谁知道如何解决这个问题?

谢谢

【问题讨论】:

  • 什么决定了应该在关系之间返回哪条消息?您可以为每个组建立一个行号,然后只返回每组中的第一个...
  • 如果线程中有超过 1 条具有相同最近日期的消息,那么它应该选择具有最大 id 值的消息。我该如何建立那个行号?
  • 其实,如果最大id,不是日期最近的那一行呢?
  • 我刚试了,结果没有返回任何记录。
  • 好点...也许你需要那个行号...

标签: php mysql join inner-join


【解决方案1】:

一种方法是为每个组建立一个行号,在这种情况下,您的组是thread_iddate_sent。使用MySql,您需要使用user-defined variables 来执行此操作:

SELECT th.id, 
    tm.message, 
    tm.date_sent, 
    tm.date_sent>tu.last_read_date AS new
FROM thread th
    JOIN thread_user tu ON th.id=tu.thread_id AND tu.user_id={$user_id}
    JOIN (
        SELECT id,
               thread_id, 
               message, 
               date_sent, 
               @rn:=IF(@prevthread_id=thread_id, @rn+1, 1) rn,
               @prevthread_id:=thread_id
        FROM thread_message, (SELECT @rn:=1, @prevthread_id:=0) t
        ORDER BY thread_id, date_sent DESC, id
    ) tm ON th.id=tm.thread_id
           AND tm.rn = 1 
ORDER BY tm.date_sent DESC

也许这对您来说更容易(但只是因为您使用的是mysql):

SELECT th.id, 
    tm.message, 
    tm.date_sent, 
    tm.date_sent>tu.last_read_date AS new
FROM thread th
    JOIN thread_user tu ON th.id=tu.thread_id AND tu.user_id={$user_id}
    JOIN thread_message tm ON th.id=tm.thread_id
    JOIN (
        SELECT thread_id, 
               id, 
               MAX(date_sent) date_sent
        FROM thread_message
        GROUP BY thread_id
    ) q ON tm.thread_id = q.thread_id 
           AND q.id = tm.id 
           AND tm.date_sent = q.date_sent
ORDER BY tm.date_sent DESC

这将返回一个任意的id 加入。

【讨论】:

  • 这还是有加入最近日期相同的两行的问题。
  • @omega -- 嗯,也许我误解了一些东西,样本数据和期望的结果会让这更容易。但是,鉴于您使用的是 mysql,请查看编辑...
  • @omega -- 还更新了行号例程,因为我现在认为我了解您的数据结构。
【解决方案2】:

在我看来,如果查询产生您所期望的结果,除了最后一个 JOIN 之外,您只需修改将只返回一行的 GROUP BY

JOIN (
      SELECT thread_id, MAX(date_sent) date_sent
      FROM thread_message
      GROUP BY thread_id
      ) q ON tm.thread_id = q.thread_id AND tm.date_sent = q.date_sent
      GROUP BY tm.date_sent
      ORDER BY tm.date_sent DESC";

【讨论】:

  • 如果您这样做,那么您可以返回与另一个线程 ID 关联的最大日期。另外还有一个问题就是没有得到最近日期的max id。
  • 第二个怎么样?
猜你喜欢
  • 1970-01-01
  • 2010-11-26
  • 2013-09-14
  • 2020-08-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-15
相关资源
最近更新 更多