2012-04-10 57 views
1

我正在構建基於mysql的聊天應用程序。只顯示mysql中的唯一條目

我的數據庫架構有如下表,

 Users    Messages 
    ================= ================= 
     id     id 
     screen_name  message 
          from 
          to 
          timestamp 

的距離,並在信息表中的字段包含發送和接收的每封郵件的用戶ID的。

我想顯示用戶($ id)和他們的朋友之一($朋友)之間的所有消息。我的查詢如下:

$query = "SELECT messages.* , users.screen_name FROM users CROSS JOIN messages "; 
$query .= "ON (messages.to = $id AND messages.from = $friend) "; 
$query .= "OR (messages.to = $friend AND messages.from = $id)"; 

問題是每個消息在結果表中都是兩次。

我試過使用DISTINCT,但它不是在這種情況下工作,或者我用它錯了。

我的查詢應該爲了讓兩個用戶之間的每條消息只有一次?

+0

'GROUP BY messages.id'? – jensgram 2012-04-10 13:29:51

+0

似乎是在做的伎倆。你能否簡單地在答案中解釋一下,以便我可以授予代表? – ppp 2012-04-10 13:32:02

+2

您正在選擇'messages。*'。使用'SELECT DISTINCT',如果這些字段中的任何一個不同(不管消息是否相同),那麼你將得到兩行。我建議你不要使用'SELECT *',而是明確地選擇你實際需要的每個單獨的字段。有關更多信息,請參見[本文](http://stackoverflow.com/questions/321299/what-is-the-reason-not-to-use-select)。 – Travesty3 2012-04-10 13:34:34

回答

3

像這樣的東西應該做的伎倆:

SELECT 
    messages.*, 
    users_from.screen_name AS from_screen_name, 
    users_to.screen_name AS to_screen_name 
FROM 
    messages 
    JOIN users AS users_from ON messages.from = users_from.id 
    JOIN users AS users_to ON messages.to = users_to.id 
WHERE 
    (messages.to = $id AND messages.from = $friend) 
    OR (messages.to = $friend AND messages.from = $id) 

這樣做是joing的「用戶」表兩次,一次是在「到」列和「從」列中的第二次。

+0

這個答案也可以。 – ppp 2012-04-10 13:52:33

1

@Travesty3已經建議DISTINCT關鍵字將只排除重複行,其中全部字段等於另一行。因此,DISTINCT關鍵字不是這裏要走的路。

但是,您可以執行的操作只是簡單地爲GROUP BY messages.id,以便每個消息ID只能獲得一行(但不能保證兩行中的哪一行將被排除)。

+0

這似乎工作得很好,但1月份提出的雙連接也是如此。兩者之間的性能有差異嗎? – ppp 2012-04-10 13:54:17

+0

@AnPel鑑於用於'JOIN'和'GROUP BY'的字段被索引,我懷疑這兩個表現都令人滿意。您可以做的是使用實際數據集上的示例查詢進行基準測試。 – jensgram 2012-04-10 13:59:21