2016-04-25 50 views
0

我知道查詢正在執行how it should但它不執行way i would like.當前查詢查找所有包含消息的對話並顯示提供的unix_timestamp後面的所有消息。JOIN查詢產生不想要的結果

與此查詢的問題是,我需要所有從application_conversation字段要顯示,不論以是否有消息提供,例如當前查詢產生以下結果:

conversation_id | conversation_participant_one | conversation_participant_two | conversation_last_message | conversation_last_message_date | message_id | message_conversation_id | message_sender_id | message_data | message_created_at 
     1      33        34      "How are you?"    2016-04-25 08:59:59   1     1      33   "How are you?" 2016-04-25 08:59:59  

以上結果是我當前的查詢提供的內容,但application_conversation表中的另一行與用戶33 and 36匹配。您可以在下面看到我期望從查詢中獲得的結果的示例。 (基本上,消息不存在的任何字段將爲空)。

conversation_id | conversation_participant_one | conversation_participant_two | conversation_last_message | conversation_last_message_date | message_id | message_conversation_id | message_sender_id | message_data | message_created_at 
     1      33        34      "How are you?"    2016-04-25 08:59:59   1     1      33   "How are you?" 2016-04-25 08:59:59 
     2      33        36       NULL     1970-01-01 00:00:00   NULL    NULL     NULL    NULL    NULL   

這裏是我目前使用的查詢:

SELECT C.*, M.* 
FROM `application_conversation` C 
INNER JOIN `application_conversation_messages` M ON M.message_conversation_id = C.conversation_id 
WHERE (C.conversation_participant_one = 33 OR C.conversation_participant_two = 33) 
AND C.conversation_created_at > FROM_UNIXTIME(0) 
AND M.message_created_at > FROM_UNIXTIME(0) 
ORDER BY M.message_created_at; 

現在這裏的問題之一是,我也有訂購的消息的message_created_at領域,如果它確實存在,這樣我就不會拉取比客戶端請求的時間戳更早的消息。在這個查詢中,這意味着消息必須存在。

如何解決不要求消息存在,但在消息上應用filter(M.message_created_at > FROM_UNIXTIME(0))(如果消息存在),如果消息不存在,則仍然返回NULL值。

我正在使用MySQL。與XAMPP軟件包捆綁在一起。不是SQLServer。

+0

如果您喜歡,請考慮遵循以下簡單的兩步操作步驟:1.如果您尚未這樣做,請提供適當的DDL(和/或sqlfiddle),以便我們可以更輕鬆地複製問題。 2.如果您尚未這樣做,請提供與步驟1中提供的信息相對應的所需結果集。 – Strawberry

回答

3

使用LEFT JOIN,並將條件放在ON子句中的application_conversation_messages表中。

SELECT C.*, M.* 
FROM `application_conversation` C 
LEFT JOIN `application_conversation_messages` M ON M.message_conversation_id = C.conversation_id AND M.message_created_at > FROM_UNIXTIME(0) 
WHERE 33 IN(C.conversation_participant_one,C.conversation_participant_two) 
AND C.conversation_created_at > FROM_UNIXTIME(0) 
ORDER BY M.message_created_at; 

INNER JOINLEFT JOIN和之間的差異的解釋見http://blog.codinghorror.com/a-visual-explanation-of-sql-joins/

0

使用左連接,而不是內部聯接,並從

​​

改變條件

AND (M.message_created_at > FROM_UNIXTIME(0) OR M.message_created_at IS NULL) 

未經測試,但我認爲它應該工作,並返回你想要的結果。

+1

關閉,但是在該條件下,它只會返回在該時間之後有M個記錄的C記錄,或者沒有M記錄在所有。 – Uueerdo

+0

哦......我的不好。我以爲這是他想要的,但你是對的。我誤解了這個問題。 – igorshmigor