JOIN查询产生不需要的结果

时间:2016-04-25 16:17:25

标签: mysql

我知道Query正在执行how it should但它没有执行way i would like.当前查询定位所有包含消息的会话,并显示所提供的unix_timestamp之后的所有消息。

此查询的问题是我需要显示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)),如果消息不存在,WHILE仍返回NULL值。

我正在使用MySQL。捆绑了XAMPP包。不是SQLServer。

2 个答案:

答案 0 :(得分:3)

使用LEFT JOIN,并将application_conversation_messages表中的条件放在ON子句中。

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/

答案 1 :(得分:0)

使用左连接而不是内连接,并从

更改条件
AND M.message_created_at > FROM_UNIXTIME(0)

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

未经测试但我认为它应该有效并返回您想要的结果。