क्वेरी इस तरह काम कर सकती है:
SELECT a.*
FROM article a
LEFT JOIN (
SELECT DISTINCT ON (article_id)
article_id, value
FROM metrics m
WHERE name = 'score'
ORDER BY article_id, date_created DESC
) m ON m.metrics_id = a.metrics_id
ORDER BY m.value DESC;
पहले , "सबसे हाल का" value
प्राप्त करें name = 'score'
के लिए सबक्वेरी में प्रति लेख m
. इस संबंधित उत्तर में प्रयुक्त तकनीक के लिए अधिक स्पष्टीकरण:
ऐसा लगता है कि आप एक बहुत ही बुनियादी ग़लतफ़हमी के शिकार हो गए हैं:
कोई "प्राकृतिक क्रम" नहीं है एक टेबल में। एक SELECT
. में , आपको ORDER BY
की आवश्यकता है अच्छी तरह से परिभाषित मानदंड। इस प्रश्न के प्रयोजन के लिए मैं एक कॉलम मान रहा हूँ metrics.date_created
. यदि आपके पास ऐसा कुछ नहीं है, तो आपके पास कोई रास्ता नहीं . है "सबसे हालिया" को परिभाषित करने के लिए और कई योग्यता पंक्तियों से मनमाने ढंग से चुनने के लिए मजबूर होना पड़ता है:
ORDER BY article_id
यह नहीं है भरोसेमंद। पोस्टग्रेज एक पंक्ति को चुनेगा जैसे वह चुनता है। तालिका में किसी भी अद्यतन या क्वेरी योजना में किसी भी परिवर्तन के साथ बदल सकता है।
अगला , LEFT JOIN
तालिका में article
और ORDER BY value
. NULL
अंतिम क्रमित होता है, इसलिए बिना योग्यता मूल्य वाले लेख अंतिम रहते हैं।
नोट:कुछ गैर-स्मार्ट ORM (और मुझे डर है कि रूबी का ActiveRecord उनमें से एक है) गैर-वर्णनात्मक और गैर-विशिष्ट id
का उपयोग करें प्राथमिक कुंजी के नाम के रूप में। आपको अपने वास्तविक कॉलम नामों के अनुकूल होना होगा, जो आपने प्रदान नहीं किए थे।
प्रदर्शन
सभ्य होना चाहिए। यह एक "सरल" क्वेरी है जहाँ तक पोस्टग्रेज़ का संबंध है। टेबल पर एक आंशिक बहु-स्तंभ अनुक्रमणिका metrics
इसे और तेज़ कर देगा:
CREATE INDEX metrics_some_name_idx ON metrics(article_id, date_created)
WHERE name = 'score';
इस क्रम में कॉलम। PostgreSQL 9.2+ में आप केवल अनुक्रमणिका स्कैन को संभव बनाने के लिए कॉलम मान जोड़ सकते हैं:
CREATE INDEX metrics_some_name_idx ON metrics(article_id, date_created, value)
WHERE name = 'score';