获取mysql中每个组的最后一行

时间:2013-10-10 10:50:24

标签: mysql

我有两张表如下:

讯息

+----+--------+-----------------+
| id | sender | body            |
+----+--------+-----------------+
| 11 | 4      | test msg one    |
| 12 | 4      | test msg        |
| 13 | 1      | this is test    |
| 14 | 4      | WANT TO SHOW G1 |
| 15 | 4      | WANT TO SHOW G2 |
+----+--------+-----------------+

message_receivers

+----------+------------+
| receiver | message_id |
+----------+------------+
| 1        |         11 |
| 1        |         12 |
| 4        |         13 |
| 1        |         14 |
| 3        |         15 |
+----------+------------+

我写了以下查询

SELECT 
    `messages`.`id`,
    `messages`.`body` ,
    `messages`.`sender`, 
    MAX(`messages`.`id`) AS MID,
    IF(`messages`.`sender`>`message_receivers`.`receiver`,`CONCAT_WS`(',',`messages`.`sender`,`message_receivers`.`receiver`), 

`CONCAT_WS`(',',`message_receivers`.`receiver`,`messages`.`sender`)) AS `conc`
FROM
    `messages`
JOIN `message_receivers` ON `messages`.`id` = `message_receivers`.`message_id`
WHERE 
    `message_receivers`.`receiver` = '4' 
    OR `messages`.`sender` = '4'
GROUP BY conc

给我以下结果

+----+-----------------+--------+------+------+
| id | body            | sender | MID  | conc |
+----+-----------------+--------+------+------+
| 11 | test msg one    | 4      |   14 | 4,1  |
| 15 | WANT TO SHOW G2 | 4      |   15 | 4,3  |
+----+-----------------+--------+------+------+

但我想要

+----+-----------------+--------+------+------+
| id | body            | sender | MID  | conc |
+----+-----------------+--------+------+------+
| 14 | WANT TO SHOW G1 | 4      |   14 | 4,1  |
| 15 | WANT TO SHOW G2 | 4      |   15 | 4,3  |
+----+-----------------+--------+------+------+

我该怎么办? 提前致谢。

2 个答案:

答案 0 :(得分:1)

标准解决方案是使用不相关的子查询,如下所示:

SELECT x.* 
  FROM my_table
  JOIN 
     ( SELECT grouping_column
            , MAX(ordering_column) max_ordering_column 
         FROM my_table 
        GROUP 
           BY grouping_column
     ) y
    ON y.grouping_column = x.grouping_column
   AND y.max_ordering_column = x.ordering_column;

或者,在多列上形成一个键......

SELECT x.* 
  FROM my_table
  JOIN 
     ( SELECT grouping_column1
            , grouping_column2
            , MAX(ordering_column) max_ordering_column 
         FROM my_table 
        GROUP 
           BY grouping_column1
            , grouping_coulmn2
     ) y
    ON y.grouping_column1 = x.grouping_column1
   AND y.grouping_column2 = x.grouping_column2
   AND y.max_ordering_column = x.ordering_column;

答案 1 :(得分:1)

使用子查询获取最大消息,然后再将其加入以获取其他字段: -

SELECT messages.id, messages.body, messages.sender, Sub1.MID, Sub1.conc
FROM messages
INNER JOIN message_receivers 
ON messages.id = message_receivers.message_id
INNER JOIN
(
    SELECT 
        IF(messages.sender>message_receivers.receiver,
            CONCAT_WS(',',messages.sender,message_receivers.receiver), 
            CONCAT_WS(',',message_receivers.receiver,messages.sender)) AS conc,
        MAX(messages.id) AS MID
    FROM messages
    JOIN message_receivers 
    ON messages.id = message_receivers.message_id
    WHERE message_receivers.receiver = '4' 
    OR messages.sender = '4'
    GROUP BY conc
) Sub1
ON Sub1.MID = messages.id
AND Sub1.conc = IF(messages.sender>message_receivers.receiver,
            CONCAT_WS(',',messages.sender,message_receivers.receiver), 
            CONCAT_WS(',',message_receivers.receiver,messages.sender))

SQL小提琴 - http://sqlfiddle.com/#!2/8ee98/2