2009-07-30 137 views
6

我有三個基本表:MySQL的選擇加入3個表

tblUsers: 

    usrID  usrFirst  usrLast 
     1  John   Smith 
     2  Bill   Jones 
     3  Jane   Johnson 

pm_data: 

id  date_sent    title   sender_id thread_id   content 
2 2009-07-29 18:46:13  Subject 1   1   111  Message 2! 
3 2009-07-29 18:47:21  Another Subject  1   222  Message 3! 

pm_info: 

id thread_id receiver_id is_read 
1  111   2   0 
2  111   3   0 
3  222   2   0 
4  222   3   0 

從本質上講,我試圖做的就是創建一個收件箱。因此,如果usrID 2(Bill Jones)打開他的收件箱,他將看到他2未讀(因此是'is_read'列)消息(線程#111和#222)。

基本上,我需要知道如何設置我的SELECT語句來JOIN所有三個表(pm_data和pm_info之間的關係帶來了消息信息,而tblUsers和pm_data之間的關係帶來了「顯示名稱」發件人),在最上面顯示最近的(通過時間戳?)線程。

因此,我們會看到這樣的事情:

<?php $usrID = 2; ?> 

<table id="messages"> 
    <tr id="id-2"> 
    <td> 
    <span> 
    From: John Smith 
    </span> 
    <span>2009-07-29 18:47:21</span> 
    </td> 
<td> 
<div>Another subject</div> 
</td></tr> 
<tr id="id-1"> 
<td> 
    <span> 
    From: John Smith 
    </span> 
    <span>2009-07-29 18:46:13</span> 
</td> 
<td> 
    <div>Subject 1</div> 
</td></tr> 
</table> 

希望這是有道理的!謝謝你的幫助!

編輯:這是我最後的答案:

我把LC的建議,並提出了基於ID的兩個表之間的關係(增加了一個名爲「MESSAGE_ID」到pm_info列)。

然後,圍繞扭捏一點點MySQL的語句來想出這個:

SELECT pm_info.is_read, sender.usrFirst as sender_name, 
pm_data.date_sent, pm_data.title, pm_data.thread_id 
FROM pm_info 
INNER JOIN pm_data ON pm_info.message_id = pm_data.id 
INNER JOIN tblUsers AS sender ON pm_data.sender_id = sender.usrID 
WHERE pm_data.date_sent IN(SELECT MAX(date_sent) FROM pm_data WHERE pm_info.message_id = pm_data.id GROUP BY thread_id) AND pm_info.receiver_id = '$usrID' ORDER BY date_sent DESC 

這似乎爲我工作(到目前爲止)。

回答

9

您需要兩個連接。像下面這樣的東西應該讓你開始(雖然我不100%理解pm_datapm_info之間的關係):

SELECT pm_info.is_read, sender.usrFirst + ' ' + sender.usrLast as sender_name, 
    pm_data.date_sent, pm_data.title, pm_data.thread_id 
FROM pm_info 
INNER JOIN pm_data ON pm_info.thread_id = pm_data.thread_id 
INNER JOIN tblUsers AS sender ON pm_data.sender_id = tblUsers.usrID 
WHERE pm_info.receiver_id = @USER_ID /*in this case, 2*/ 
ORDER BY pm_data.date_sent DESC 

我假設pm_datapm_info之間的關係是線程ID。如果不是,您應該可以根據需要調整上述內容。我也按這裏發送日期排序,但它不會把線程保持在一起。我不確定你是否希望將它們保持在一起,或者不是按照你所說的話來說明問題。


如果你想保持線程一起,你需要一個更復雜的查詢:

SELECT pm_info.is_read, sender.usrFirst + ' ' + sender.usrLast as sender_name, 
    pm_data.date_sent, pm_data.title, pm_data.thread_id 
FROM pm_info 
INNER JOIN pm_data ON pm_info.thread_id = pm_data.thread_id 
INNER JOIN tblUsers AS sender ON pm_data.sender_id = tblUsers.usrID 
INNER JOIN (SELECT thread_id, MAX(date_sent) AS max_date 
      FROM pm_data 
      GROUP BY thread_id) AS most_recent_date 
      ON pm_data.thread_id = most_recent_date.thread_id 
WHERE pm_info.receiver_id = @USER_ID /*in this case, 2*/ 
ORDER BY most_recent_date.max_date DESC, pm_data.thread_id, 
    pm_data.date_sent DESC 

此查詢使用子查詢找到每個線程的最新的修改日期,然後首先排序。

+0

謝謝lc,您的回覆。您的複雜查詢絕對是我前進的方向。它不會拋出任何錯誤,但它會做一些事情:1)它仍然顯示線程的所有部分(即使用戶發送的與線程有關的項目),以及2)它以重複的方式顯示它。讓我知道你是否需要我更加明確。謝謝。 – Dodinas 2009-07-30 03:36:42

3

要獲取的郵件列表供用戶沿誰,當他們送了它,你可以用下面的查詢:

select 
    s.usrFirst + ' ' + s.usrLast as SenderName, 
    m.Title, 
    m.DateSent, 
    i.IsRead 
from 
    tblUsers r 
    inner join pm_info i on 
     r.receiver_id = i.receiver_id 
    inner join pm_data m on 
     i.thread_id = m.thread_id 
    inner join tblUsers s on 
     m.sender_id = s.userID 
where 
    r.usrid = @id 

這需要的事實,你可以加入牌桌優勢(在這裏,tblUsers顯示了兩次:一次爲收件人,再次爲發件人)。

如果您只想查看未讀郵件,可以在where子句中輸入and i.IsRead = 0