简体   繁体   English

仅显示第一条记录进行分组

[英]Group by only showing the first record

I'm trying to grab some conversation records in my database however only show the latest result. 我正在尝试获取数据库中的一些对话记录,但是仅显示最新结果。 I've tried the below however it groups by the first record found is there a way I can make it group by the last record on the dateline colum 我尝试了下面的方法,但是按找到的第一个记录进行分组有一种方法可以使它按日期行的最后一条记录进行分组

  SELECT DISTINCT*
  FROM table_messages 
  WHERE fromid=4 OR toid=4
  GROUP BY convoid
  ORDER BY dateline desc

My table is like the below 我的桌子如下

pmid - fromid - toid - convoid - dateline
 1       4        15      3      1461079193
 2       4        15      3      1461079200
 3       15        4      3      1461079220
 4       15        4      3      1461079230
 5       4        15      3      1461079270

To get a list of all the conversations for a specific user, and the last message sent (and it's details) for each conversation, in a single query: 要在单个查询中获取特定用户的所有对话的列表,以及每个对话的最后发送的消息(及其详细信息),请执行以下操作:

SELECT
    convo.convoid,
    message.pmid,
    message.dateline,
    CASE WHEN fromid = 4 then "SENT" ELSE "RECEIVED" as direction
FROM
    (SELECT convoid, max(dateline) as maxdateline FROM table_messages GROUP BY convoid) convo
    INNER JOIN table_messages message
        ON convo.convoid = message.convoid AND
            convo.maxdateline = message.dateline
WHERE 
    fromid = 4 or toid = 4

Here we are working with two sets again. 在这里,我们再次处理两组。 The first (from the FROM ) is a list of all convoid's and their max dateline . 第一个(来自FROM )是所有convoid's列表及其最大dateline Then we INNER JOIN those with the same table on the relationship of convoid and dateline. 然后,我们对那些与相同表具有相同关系的contain和dateline进行INNER JOIN This will give us a record set of every conversation and it's most recent message. 这将为我们提供每次对话的记录集,以及它的最新消息。

Then we restrict in the WHERE clause to get just the conversations where either the fromid or the toid is the user you are interested in. 然后,我们限制WHERE子句,以仅获取fromidtoid是您感兴趣的用户的对话。

For the fun, I added the CASE statement, just to bring in more information about that last message sent (whether it was sent by the user or received by the user). 为了好玩,我添加了CASE语句,只是为了引入有关最后发送的消息的更多信息(无论是由用户发送还是由用户接收)。


It MIGHT be quicker to do: 可能会更快地做到:

SELECT
    convo.convoid,
    message.pmid,
    message.dateline,
    CASE WHEN fromid = 4 then "SENT" ELSE "RECEIVED" as direction
FROM
    (SELECT convoid, max(dateline) as maxdateline FROM table_messages GROUP BY convoid WHERE fromid = 4 or toid = 4) convo
    INNER JOIN table_messages message
        ON convo.convoid = message.convoid AND
            convo.maxdateline = message.dateline

Depending on how MySQL optimizes the first query. 取决于MySQL如何优化第一个查询。 If it tries to get every conversation and then the last message, then restricts it for the user then you can force the optimizer to instead, with this version, only get conversations for the user, then get the latest message for those conversations. 如果它尝试获取每个对话,然后获取最后一条消息,然后将其限制为用户使用,则您可以强制优化器改为使用此版本,仅为用户获取对话,然后获取这些对话的最新消息。 My bet though is that it's a wash and that MySQL will properly optimize the first query to do what is explicitly stated in the second. 不过我敢打赌,这是洗钱,MySQL会适当地优化第一个查询以执行第二个查询中明确指出的事情。 But... I figured just in case, I would put it here. 但是...我想以防万一,我把它放在这里。

For readability sake, I like the first query better since one can very quickly see the conditions in the main query's WHERE clause. 出于可读性考虑,我更喜欢第一个查询,因为可以非常快地看到主查询的WHERE子句中的条件。 Otherwise you have to hunt in the subquery. 否则,您必须在子查询中搜寻。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM