आपको प्रति सप्ताह एक डेटा आइटम और लक्ष्य (प्रति कंपनी कुल गणना से पहले) की आवश्यकता है। यह एक सादा क्रॉस जॉइन
है generate_series()
. के बीच और लक्ष्य
. (संभवतः) महंगा हिस्सा वर्तमान राज्य
. प्राप्त करना है अपडेट
. से प्रत्येक के लिए। जैसे @Paul ने पहले ही सुझाव दिया था
, एक पार्श्व
शामिल हों सबसे अच्छा उपकरण की तरह लगता है। इसे केवल अपडेट
के लिए करें , हालांकि, और LIMIT 1
. के साथ तेज़ तकनीक का उपयोग करें ।
और <के साथ दिनांक प्रबंधन को सरल बनाएं कोड>डेट_ट्रंक () ।
SELECT w_start
, g.company_id
, count(*) FILTER (WHERE u.status = 'green') AS green_count
, count(*) FILTER (WHERE u.status = 'amber') AS amber_count
, count(*) FILTER (WHERE u.status = 'red') AS red_count
FROM generate_series(date_trunc('week', NOW() - interval '2 months')
, date_trunc('week', NOW())
, interval '1 week') w_start
CROSS JOIN goals g
LEFT JOIN LATERAL (
SELECT status
FROM updates
WHERE goal_id = g.id
AND created_at < w_start
ORDER BY created_at DESC
LIMIT 1
) u ON true
GROUP BY w_start, g.company_id
ORDER BY w_start, g.company_id;
इसे तेज़ बनाने के लिए आपको एक बहु-स्तंभ अनुक्रमणिका need चाहिए :
CREATE INDEX updates_special_idx ON updates (goal_id, created_at DESC, status);
created_at
. के लिए अवरोही क्रम सबसे अच्छा है, लेकिन सख्ती से जरूरी नहीं है। पोस्टग्रेज इंडेक्स को लगभग उतनी ही तेजी से पीछे की ओर स्कैन कर सकता है। ( हालांकि, कई स्तंभों के उल्टे क्रम के लिए लागू नहीं है।
)
कि . में अनुक्रमणिका स्तंभ गण। क्यों?
और तीसरा कॉलम status
केवल तेज़ इंडेक्स-ओनली स्कैन
की अनुमति देने के लिए जोड़ा गया है अपडेट
पर . संबंधित मामला:
9 सप्ताह के लिए 1k लक्ष्य (आपके 2 महीने का अंतराल कम से कम 9 सप्ताह के साथ ओवरलैप होता है) केवल 1k पंक्तियों की दूसरी तालिका के लिए केवल 9k इंडेक्स लुक-अप की आवश्यकता होती है। इस तरह की छोटी तालिकाओं के लिए, प्रदर्शन में कोई समस्या नहीं होनी चाहिए। लेकिन एक बार जब आपके पास प्रत्येक तालिका में कुछ हज़ार और हो जाते हैं, तो क्रमिक स्कैन के साथ प्रदर्शन खराब हो जाएगा।
w_start
प्रत्येक सप्ताह की शुरुआत का प्रतिनिधित्व करता है। नतीजतन, गिनती सप्ताह की शुरुआत के लिए है। आप कर सकते हैं यदि आप जोर देते हैं तो अभी भी वर्ष और सप्ताह (या कोई अन्य विवरण आपके सप्ताह का प्रतिनिधित्व करते हैं) निकालें:
EXTRACT(isoyear from w_start) AS year
, EXTRACT(week from w_start) AS week
ISOYEAR
, जैसे @Paul ने समझाया।
संबंधित:
- पोस्टग्रेएसक्यूएल में लेटरल और सबक्वेरी में क्या अंतर है?
- प्रति उपयोगकर्ता नवीनतम रिकॉर्ड पुनर्प्राप्त करने के लिए क्वेरी द्वारा समूह को अनुकूलित करें
- पहले चुनें प्रत्येक ग्रुप बाय ग्रुप में पंक्ति?
- PostgreSQL:किसी क्वेरी के लिए 'मिनट के हिसाब से' पंक्तियों की चल रही गिनती