仅按组显示第一条记录

时间:2016-04-19 15:14:44

标签: php mysql

我正在尝试在我的数据库中获取一些会话记录,但只显示最新结果。我已经尝试过以下但是根据发现的第一条记录它是否有一种方法我可以通过dateline colum上的最后一条记录进行分组

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

我的表格如下

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

1 个答案:

答案 0 :(得分:0)

在单个查询中获取特定用户的所有会话列表以及每个会话发送的最后一条消息(及其详细信息):

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

我们再次使用两套。第一个(来自FROM)是所有convoid's及其最大dateline的列表。然后我们INNER JOIN那些与convoid和dateline关系相同的表。这将为我们提供每个对话的记录集及其最新消息。

然后我们在WHERE子句中限制只获得fromidtoid是您感兴趣的用户的对话。

为了好玩,我添加了CASE语句,只是为了提供有关最后发送的消息的更多信息(无论是由用户发送还是由用户接收)。

MIGHT 可以更快地完成:

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

取决于MySQL如何优化第一个查询。如果它尝试获取每个对话,然后是最后一条消息,然后将其限制为用户,那么您可以强制优化器改为使用此版本,仅为用户获取对话,然后获取这些对话的最新消息。我的赌注是,它是一个洗,MySQL将正确优化第一个查询,以执行第二个中明确说明的内容。但是......我想以防万一,我会把它放在这里。

为了便于阅读,我更喜欢第一个查询,因为可以非常快速地查看主查询的WHERE子句中的条件。否则你必须在子查询中寻找。