2009-07-30 18 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 (बिल जोन्स) अपना इनबॉक्स खोलता है, तो वह देखेंगे कि वह 2 अपठित (इसलिए 'is_read' कॉलम) संदेश (धागे # 111 और # 222) हैं।

असल में, मुझे यह जानने की जरूरत है कि सभी तीन तालिकाओं में शामिल होने के लिए मेरा चयन कथन कैसे सेट करें (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> 

उम्मीद है कि इस समझ में आता है! किसी भी मदद के लिए धन्यवाद!

संपादित करें: यहाँ मेरी अंतिम जवाब है:

मैं नियंत्रण रेखा की सलाह ले लिया, और आईडी के आधार पर दो तालिकाओं के बीच संबंध बनाया (एक कॉलम '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_data और pm_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_data और pm_info के बीच संबंध संभालने हूँ धागा आईडी है। यदि ऐसा नहीं है, तो आपको उपर्युक्त समायोजन करने में सक्षम होना चाहिए जो भी आपको चाहिए। मैंने यहां भेजे गए दिनांक से भी क्रमबद्ध किया है, लेकिन यह धागे को को एक साथ नहीं रखेगा। मुझे यकीन नहीं है कि क्या आप उन्हें एक साथ रखना चाहते हैं या नहीं, जिस तरह से आपने अपना प्रश्न phrased किया है।


आप धागे एक साथ रखने के लिए चाहते हैं, आप एक और अधिक जटिल क्वेरी की आवश्यकता होगी:

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 

इस क्वेरी, प्रत्येक थ्रेड के लिए सबसे हाल ही में संशोधित तिथि को खोजने के लिए एक subselect का उपयोग करता है तो इस तरह से पहले।

+0

धन्यवाद एलसी, आपके उत्तर के लिए। आपकी जटिल क्वेरी निश्चित रूप से जिस दिशा में मैं जा रहा हूं वह निश्चित रूप से है। यह किसी भी त्रुटि को फेंक नहीं रहा है, लेकिन यह कुछ चीजें कर रहा है: 1) यह अभी भी धागे के सभी हिस्सों को दिखाता है (यहां तक ​​कि उपयोगकर्ता के धागे से संबंधित आइटम भेजे गए आइटम) और 2) यह इसे डुप्लिकेट में दिखा रहा है। अगर आपको मुझे और अधिक स्पष्ट होने की आवश्यकता है तो मुझे बताएं। धन्यवाद। – Dodinas

+0

@Dodinas 1) यह धागे के सभी हिस्सों को दिखाएगा। यदि आप सबकुछ दिखाना नहीं चाहते हैं, तो आपको यह सोचना होगा कि आप वास्तव में क्या फ़िल्टर करना चाहते हैं और इसे WHERE क्लॉज में जोड़ें। 'Pm_data' और' pm_info' के बीच रिश्ते में और भी अधिक हो सकता है जो मुझे याद आ रही है, क्योंकि मुझे अभी भी थ्रेड आईडी है ... 2) क्या आप टेबल के कुछ और पोस्ट कर सकते हैं ' सामग्री इसलिए मैं देख सकता हूं कि यह गलत कहां जा रहा है? इनर जॉइन को डुप्लिकेट में किसी भी पंक्ति का उत्पादन नहीं करना चाहिए। यह भी संभवतः आपकी त्रुटि क्वेरी निष्पादित करने के बाद PHP में है ... –

+0

@lc: उत्तर के लिए धन्यवाद। असल में, मुझे नहीं लगता कि समस्या PHP के साथ है। हालांकि, यह मेरे डीबी संरचित तरीके से एक मुद्दा हो सकता है। असल में, मैंने जो पोस्ट किया है वह वह सारणी है जिसके साथ मैं काम कर रहा हूं। 'Thread_id' एकमात्र चीज है जो दो तालिकाओं से संबंधित है। शायद मुझे अपने डीबी संरचना में बदलाव करने की ज़रूरत है? – Dodinas

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 दो बार दिखाता है: एक बार प्राप्तकर्ता के लिए, और फिर प्रेषक के लिए)।

यदि आप केवल अपठित संदेशों को देखना चाहते हैं, तो आप खंड में and i.IsRead = 0 डाल सकते हैं।

संबंधित मुद्दे