MySQL:使用UNION,MAX和GROUP BY的奇怪行为

时间:2013-12-20 20:30:53

标签: mysql sql

我有一个存储消息的简单表:

+----+--------+----------+--------------+------+
| id | sender | receiver |      dt      | text |
+----+--------+----------+--------------+------+
| 1  | a      | b        | ..19.26.00.. | msg1 |
+----+--------+----------+--------------+------+
| 2  | c      | b        | ..19.26.02.. | msg2 |
+----+--------+----------+--------------+------+
| 3  | b      | a        | ..19.26.03.. | msg3 |
+----+--------+----------+--------------+------+

我想在对话中选择最近的消息。例如,对于我想要的b:

+--------------+--------------+------+
| conversation |  MAX(maxdt)  | text |
+--------------+--------------+------+
| ab           | ..19.26.03.. | msg3 |
+--------------+--------------+------+
| cb           | ..19.26.02.. | msg2 |
+--------------+--------------+------+

所以我使用这个查询:

SELECT conversation, MAX(maxdt), text FROM
(SELECT CONCAT(sender, receiver) AS conversation, MAX(dt) AS maxdt,  text
FROM message
WHERE receiver='b' GROUP BY conversation
UNION 
SELECT CONCAT(receiver, sender) AS conversation, MAX(dt) AS maxdt, text
FROM message
WHERE sender='b' GROUP BY conversation) AS x
GROUP BY conversation

但结果是:

+--------------+--------------+------+
| conversation |  MAX(maxdt)  | text |
+--------------+--------------+------+
| ab           | ..19.26.03.. | msg1 |
+--------------+--------------+------+
| cb           | ..19.26.02.. | msg2 |
+--------------+--------------+------+

因此,日期时间值是正确的,但文本来自错误的元组!

有什么建议吗? SQL Fiddle

2 个答案:

答案 0 :(得分:2)

好的我有一个可能的解决方案,工作SQL小提琴。试试这个:

SELECT CONCAT('b',other) AS conversation, text, dt AS maxdt FROM 
(
    SELECT IF(sender='b',receiver, sender) AS other, dt,  text
    FROM message
    WHERE (receiver='b' OR sender='b') order by dt desc
) 
AS TBL group by other

如果您希望对话字段标准化,您可以将CONCAT('b',其他)作为对话。

答案 1 :(得分:0)

     SELECT CONCAT(sender,receiver) AS conversation,maxdt,text 
     FROM
         (SELECT max(dt) as maxdt FROM message WHERE sender = 'b'
            UNION
          SELECT max(dt) as maxdt FROM message WHERE receiver = 'b')T1,
          message T2
     WHERE T1.maxdt = T2.dt
     AND (T2.receiver = 'b' OR T2.sender = 'b')

sqlFiddle