2013-12-20 141 views
1

奇怪的行爲,我做了一個簡單的表,用於存儲信息:MySQL的:使用UNION,MAX和GROUP BY

+----+--------+----------+--------------+------+ 
| 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

+0

即其中文本字段在表中列出的順序; GROUP_CONCAT(text),你應該看到 – Cez

+0

你會想回到那張表來獲得適當的'text'值。 –

回答

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',other)作爲對話。

+0

我編輯它來標準化會話變量並使別名更明智 –

+0

在'select'子句中使用'text'和'dt'使用這裏描述的MySQL的擴展(http://dev.mysql.com/doc /refman/5.7/en/group-by-extensions.html)。請注意,文檔*明確警告不要在組中的所有行的值相同時使用它。它明確指出使用*不確定*值。換句話說,儘管查詢可能工作,但顯然它使用了數據庫中不支持的功能。 –

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

+0

這不適用於所有情況:[sqlFiddle](http://www.sqlfiddle.com/#!2/e286c/2) – xonya

+0

我認爲是錯誤的。我以爲你想要最新的消息,其中b是發送者UNION,其中b是接收者的最新消息 –