MySQL Select 3 Tabloları JOIN

2 Cevap php

Ben üç temel tablo vardır:

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

Esasen, ben ne çalışıyorum bir gelen kutusu oluşturmak olduğunu.

UsrID 2 (Bill Jones) onun gelen kutusu açar Yani, eğer, o göreceksiniz ki o 2 okunmamış (dolayısıyla 'is_read' sütunu) mesajları (ipler # 111 ve # 222).

Temelde, ben, her üç tablo (tblUsers ve pm_data arasındaki ilişki gönderenin 'görüntü adı' getiriyor ederken pm_data ve pm_info arasındaki ilişki, ileti bilgi getiriyor) JOIN benim SELECT deyimi kurmak için bilmek gerekir üstüne (zaman damgası?) En son konu göstermek için.

Böylece, biz böyle bir şey görecekti:

<?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>

Umarım bu mantıklı! Herhangi bir yardım için teşekkür ederiz!

EDIT: İşte benim son cevabı:

Ben LC tavsiye aldı ve kimliği dayalı iki tablo arasındaki ilişkiyi (pm_info için 'message_id' adında bir sütunu eklenmiştir) yaptı.

Sonra, bu ile gelip biraz etrafında MySQL deyimi tweaked:

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

Bu (şimdiye kadar) benim için iş gibi görünüyor.

2 Cevap

İki katılır gerekir. (Ben% 100 pm_data ve pm_info arasındaki ilişkiyi anlamıyorum rağmen) aşağıdaki gibi bir şey başlamak gerekir:

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

I pm_data ve pm_info parçacığı kimliği arasındaki ilişkiyi varsayarak yaşıyorum. Değilse, size ihtiyacınız ne olursa olsun yukarıdaki ayarlamak gerekir. Ben de buraya gönderildi tarihe göre sıralanır, ancak it won't keep the threads together ettik. Ben size soru phrased ettik yoldan birlikte ya da değil, onları tutmak istiyorsanız emin değilim.


If you want to keep threads together, daha karmaşık bir sorgu gerekir:

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

Bu sorgu her iş parçacığı için en son değiştirilme tarihini bulmak için bir subselect kullanır, sonra bu ilk sıralar.

Kim ve bunu gönderdi zaman, aşağıdaki sorguyu kullanabilirsiniz ile birlikte bir kullanıcı için mesajların listesini almak için:

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

Bu can (: Bir kez alıcı için, ve tekrar gönderene için burada, tblUsers iki kere gösterir) kendisine bir tablo katılmak olduğunu aslında yararlanır.

Yalnızca okunmamış iletileri görmek istiyorsanız, size where fıkrasında and i.IsRead = 0 koyabilirsiniz.