समस्या GROUP BY
. के व्यवहार के लिए MySQL-विशिष्ट एक्सटेंशन के कारण है खंड। अन्य डेटाबेस एक त्रुटि फेंक देंगे... SELECT सूची में ऑन-एग्रीगेट जैसा कुछ"। (यदि हम sql_mode में ONLY_FULL_GROUP_BY शामिल करते हैं, तो हम एक समान त्रुटि फेंकने के लिए MySQL प्राप्त कर सकते हैं।)
अभिव्यक्ति के साथ समस्या messages.created
क्या यह GROUP BY में एक अनिश्चित पंक्ति के मान को संदर्भित करता है। ORDER BY ऑपरेशन, GROUP BY ऑपरेशन के बाद, प्रोसेसिंग में बहुत बाद में होता है।
प्रत्येक समूह के लिए "नवीनतम" बनाने के लिए, कुल . का उपयोग करें अभिव्यक्ति MAX(messages.created)
।
उसी पंक्ति से अन्य मान प्राप्त करना थोड़ा अधिक जटिल है।
मान लें कि created
अद्वितीय है किसी दिए गए conversation_id
. के भीतर समूह (या, यदि इसकी कोई गारंटी नहीं है कि यह अद्वितीय नहीं है, और आप created
के लिए समान मान वाली एकाधिक पंक्तियों को वापस करने के साथ ठीक हैं ...
नवीनतम created
get प्राप्त करने के लिए प्रत्येक conversation_id
. के लिए
SELECT lm.conversation_id
, MAX(lm.created) AS created
FROM conversation lc
JOIN message lm
ON lm.conversation_id = lc.id
WHERE (lc.creator_id = :userId OR lc.to_id = :userId)
GROUP BY lm.conversation_id
आप उस नवीनतम created
. के साथ पूरी पंक्ति प्राप्त करने के लिए, एक इनलाइन दृश्य के रूप में इसका उपयोग कर सकते हैं
SELECT c.*
, m.*
FROM ( SELECT lm.conversation_id
, MAX(lm.created) AS created
FROM conversation lc
JOIN message lm
ON lm.conversation_id = lc.id
WHERE (lc.creator_id = :userId OR lc.to_id = :userId)
GROUP BY lm.conversation_id
) l
JOIN conversation c
ON c.id = l.conversation_id
JOIN messages m
ON m.conversation_id = l.conversation_id
AND m.created = l.created
WHERE (c.creator_id = :userId OR c.to_id = :userId)
नोट:
आप एक ORDER BY
जोड़ सकते हैं पंक्तियों को वापस करने का आदेश देने के लिए खंड, हालांकि आपको इसकी आवश्यकता है।
WHERE
बाहरी क्वेरी पर खंड संभवतः बेमानी और अनावश्यक है।
हम SELECT *
. के इस्तेमाल से बचना पसंद करते हैं , और लौटाए जाने वाले भावों को स्पष्ट रूप से सूचीबद्ध करना पसंद करते हैं।