2017-08-25 35 views
0

我有一個表來存儲與以下幾列信息:MySQL的合併查詢正確

+----+-----------+-----------+--------------+---------+------+---------------------+---------+ 
| ID | parent_id | author_id | recipient_id | subject | body | created    | is_read | 
+----+-----------+-----------+--------------+---------+------+---------------------+---------+ 
| 1 | 0   | 51  | 52   | sub1 | bod1 | 2017-08-24 15:49:29 | 0 | 
---------------------------------------------------------------------------------------------- 
| 2 | 1   | 52  | 51   | NULL | bod2 | 2017-08-24 15:52:29 | 0 | 
---------------------------------------------------------------------------------------------- 
| 3 | 1   | 51  | 52   | NULL | bod3 | 2017-08-24 15:55:29 | 0 | 
---------------------------------------------------------------------------------------------- 

從這個表,我想提取:每個「線」的

  • 主題 (一個線程的parent_id爲0,對於該主題的回覆具有NULL值)
  • 創建在最近的消息的日期讀
  • 在線程未讀消息的數量,其中recipient_id是等於當前USER_ID

例如:

收件人ID 51

+----+-----------+-----------+--------------+ 
| subject | last_message_date_time | unread | 
+----+-----------+-----------+--------------+ 
| sub1 | 2017-08-24 15:55:29 | 1  | 
--------------------------------------------- 

收件人ID 52

+----+-----------+-----------+--------------+ 
| subject | last_message_date_time | unread | 
+----+-----------+-----------+--------------+ 
| sub1 | 2017-08-24 15:55:29 | 2  | 
--------------------------------------------- 

我已經寫了一些個人查詢,但我竭力把他們所有連接在一起(51爲當前用戶ID):

1.所有線程爲當前用戶(線程具有爲0的PARENT_ID)

SELECT m1.ID, m1.subject 
FROM messages m1 
WHERE (m1.author_id = 51 OR m1.recipient_id = 51) 
    AND m1.parent_id = 0 

2.最後的消息的線程中的時間戳

SELECT MAX(m2.created) as last_message_time_date 
FROM messages m2 
WHERE (author_id = 51 OR recipient_id = 51) 

3.當用戶CURENT不是筆者

SELECT COUNT(m3.ID) as unread 
FROM messages m3 
WHERE recipient_id = 51 
    AND is_read = 0 

我得到儘可能這個未讀郵件數:

SELECT m1.ID, m1.subject, MAX(m2.created), COUNT(m3.ID) 
FROM messages m1 
LEFT JOIN 
    (SELECT created, parent_id 
    FROM messages) AS m2 
    ON m1.ID = m2.parent_id 
LEFT JOIN 
    (SELECT ID, parent_id 
    FROM messages 
    WHERE recipient_id = 51 AND is_read = 0) AS m3 
    ON (m1.ID = m3.parent_id OR m1.ID = m3.ID) 
WHERE (m1.author_id = 51 OR m1.recipient_id = 51) 
    AND m1.parent_id = 0 

我的問題是,計數返回一個不正確的值(超過它應該)。任何建議將不勝感激,非常感謝提前。

+2

改進/建議你能否提供一些示例數據和預期的結果? – Noob

+0

當然,我已經用一些示例數據更新了我的問題。非常感謝。 – Ric

+1

你是否也可以添加你想要的結果?你想從查詢中得到什麼結果 – Noob

回答

0

如此看來distinct對方回答:

SELECT m1.ID, m1.subject, m2.author_id, MAX(m2.created) as last_message_date_time, COUNT(distinct m3.ID) as unread 
FROM messages m1 

LEFT JOIN messages m2 
    ON (m1.ID = m2.parent_id OR m1.ID = m2.ID) 

LEFT JOIN 
    (
    SELECT ID, parent_id 
    FROM messages 
    WHERE is_read = 0 
     AND recipient_id = 51 
    ) 
    AS m3 
    ON (m1.ID = m3.parent_id OR m1.ID = m3.ID) 

WHERE (m1.author_id = 51 OR m1.recipient_id = 51) 
    AND m1.parent_id = 0 

GROUP BY m1.ID 

仍然是開放的雖然:)

+0

此查詢不返回您指定的列。你聲稱什麼是實際的解決方案?這裏m2.author_id每個組可以有多行,所以你需要對它進行分組或聚合它 - 讀取ONLY_FULL_GROUP_BY。兩個不在鍵上的左連接有時可以通過集合中的唯一方式解決,但有時候意味着需要兩個左連接的內連接。請閱讀並在[mcve]上採取行動。例如你的MySQL版本是什麼?例如你的約束是什麼? – philipxy

+0

感謝您的回覆。我創建了一個SQL小提琴,希望能夠更好地展示我正在嘗試做什麼以及迄今爲止如何實現它:http://sqlfiddle.com/#!9/7d3858/16 我已經刪除了author_id部分,因爲我意識到我不需要這個查詢。 – Ric

+0

感謝您的小提琴和簡化,我看到上面有一條評論。請在你的問題中編輯澄清,而不是評論。請把小提琴代碼和鏈接也放在你的問題。 – philipxy