2012-08-28 80 views
8

比方說,這是數據庫結構的最後一條消息:私人消息傳遞系統。清單每個對話

enter image description here

SELECT * FROM `pms` where id_to = 1 or id_from = 1 

這將返回所有他recived或發送的消息,

所以,我該怎麼找回來自的最後一條消息,每個用戶1可能擁有的對話?

PD:我把它叫做談話時,有兩個用戶

CNC中

因此,考慮該數據庫的內容之間的一個或多個消息:

enter image description here

我們希望得到ID 4和6

回答

7

這是假設id是一個自動遞增列:

SELECT MAX(id) AS id 
FROM pms 
WHERE id_to = 1 OR id_from = 1 
GROUP BY (IF(id_to = 1, id_from, id_to)) 

假設你有id_fromid_to索引,這種變化很可能會表現得更好,因爲MySQL不知道做什麼用的或做的事:

SELECT MAX(id) AS id FROM 
(SELECT id, id_from AS id_with 
FROM pms 
WHERE id_to = 1 
UNION ALL 
SELECT id, id_to AS id_with 
FROM pms 
WHERE id_from = 1) t 
GROUP BY id_with 

下面是如何獲得這些消息的這些ID:

SELECT * FROM pms WHERE id IN 
    (SELECT MAX(id) AS id FROM 
    (SELECT id, id_from AS id_with 
    FROM pms 
    WHERE id_to = 1 
    UNION ALL 
    SELECT id, id_to AS id_with 
    FROM pms 
    WHERE id_from = 1) t 
    GROUP BY id_with) 
+0

這似乎工作!我會給它一些測試,並讓你知道。謝謝! –

+0

@ToniMichelCaubet,另一個更新來返回整個消息。 –

+0

所以這表現更好? –

1

此查詢應該工作:

SELECT a.* 
FROM pms a 
    INNER JOIN (
       SELECT id_to, id_from, MAX(fecha) AS fecha 
       FROM pms 
       WHERE (id_to = 1 OR id_from = 1) 
       GROUP BY LEAST(id_to, id_from) 
       ) b 
       ON a.fecha = b.fecha AND 
        (a.id_to = b.id_to OR 
        a.id_from = b.id_from); 

See example @ sqlfiddle here

如果有idPRIMARY KEY和你正在按時間順序記錄消息,那麼它可以被進一步優化和簡化爲:

SELECT a.* 
FROM pms a 
    INNER JOIN (
       SELECT MAX(id) AS id 
       FROM pms 
       WHERE (id_to = 1 OR id_from = 1) 
       GROUP BY LEAST(id_to, id_from) 
       ) b 
       ON a.id = b.id; 
+0

報告了以下錯誤:每個派生表都必須具有其自己的別名 –

+0

ohh ok ..忘記派生表「b」的alis。更新查詢,現在就試試。 – Omesh

+0

gosh ...報告了以下錯誤:Where子句中的列'id_to'不明確 –

3
select pms.* from pms 
inner join 
    (select max(fecha) as max_fecha, 
      if(id_to<id_from,id_to,id_from) min_id, 
      if(id_to<id_from,id_from,id_to) max_id 
     from pms where id_to = 1 or id_from = 1 
     group by if(id_to<id_from,id_to,id_from),if(id_to<id_from,id_from,id_to)) t 
    on (if(pms.id_to<pms.id_from,pms.id_to,pms.id_from)=t.min_id) 
     and (if(pms.id_to<pms.id_from,pms.id_from,pms.id_to)=t.max_id) 
     and (pms.fecha=t.max_fecha) 

此外,如果id_to和您的表中的id_from足夠小,以防止語句溢出(id_to + id_from),這裏是簡單查詢:

select pms.* from pms 
inner join 
    (select max(fecha) as max_fecha, id_to+id_from as sum_id 
     from pms where id_to = 1 or id_from = 1 
     group by id_to+id_from) t 
    on ((pms.id_to+pms.id_from)=t.sum_id) 
     and (pms.fecha=t.max_fecha) 
where pms.id_to = 1 or pms.id_from = 1 
+0

這是顯示最後一條消息每個對話的每個用戶。它接近,但我們只想要每個對話的最後一條消息 –

+1

請嘗試固定查詢。 – valex

+0

作品!將給它一些測試,並會讓你知道 –