असल में, आपको एक विंडो फ़ंक्शन की आवश्यकता है। यह आजकल एक मानक विशेषता है। वास्तविक विंडो फ़ंक्शंस के अतिरिक्त, आप कोई भी . का उपयोग कर सकते हैं एक OVER
. जोड़कर Postgres में विंडो फंक्शन के रूप में एग्रीगेट फंक्शन खंड।
यहाँ विशेष कठिनाई है विभाजन प्राप्त करना और सही क्रम को क्रमबद्ध करना:
SELECT ea_month, id, amount, ea_year, circle_id
, sum(amount) OVER (PARTITION BY circle_id
ORDER BY ea_year, ea_month) AS cum_amt
FROM tbl
ORDER BY circle_id, month;
और नहीं GROUP BY
।
प्रत्येक पंक्ति के योग की गणना विभाजन में पहली पंक्ति से वर्तमान पंक्ति तक की जाती है - या मैनुअल को सटीक होने के लिए उद्धृत करते हुए:
<ब्लॉकक्वॉट>
डिफ़ॉल्ट फ़्रेमिंग विकल्प RANGE UNBOUNDED PRECEDING
. है , जो RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
के समान है . साथORDER BY
, यह फ्रेम को विभाजन से सभी पंक्तियों को वर्तमान पंक्ति के अंतिम ORDER BY
के माध्यम से प्रारंभ करने के लिए सेट करता है सहकर्मी ।
... जो संचयी या चालू योग है जिसके बाद आप हैं। बोल्ड जोर मेरा।
समान (circle_id, ea_year, ea_month)
. के साथ पंक्तियाँ "साथी" . हैं इस क्वेरी में। वे सभी एक ही चल रहे योग को दिखाते हैं, जिसमें सभी साथियों को योग में जोड़ा जाता है। लेकिन मुझे लगता है कि आपकी तालिका UNIQUE
है पर (circle_id, ea_year, ea_month)
, तो सॉर्ट क्रम नियतात्मक होता है और किसी भी पंक्ति में पीयर नहीं होते हैं।
नए frame_exclusion
. के साथ साथियों को शामिल/बहिष्कृत करने के लिए 11 जोड़े गए टूल पोस्टग्रेज़ करता है विकल्प। देखें:
- एक ही समूह में नहीं सभी मानों को एकत्रित करना
अब, ORDER BY ... ea_month
महीने के नामों के लिए स्ट्रिंग के साथ काम नहीं करेगा . पोस्टग्रेज़ स्थानीय सेटिंग के अनुसार वर्णानुक्रम में क्रमबद्ध होंगे।
यदि आपके पास वास्तविक date
है आपकी तालिका में संग्रहीत मान आप ठीक से सॉर्ट कर सकते हैं। यदि नहीं, तो मैं ea_year
. को बदलने का सुझाव देता हूं और ea_month
एक कॉलम के साथ mon
प्रकार का date
आपकी तालिका में।
-
आपके पास जो है उसे
to_date()
with से रूपांतरित करें :to_date(ea_year || ea_month , 'YYYYMonth') AS mon
-
प्रदर्शन के लिए, आप
to_char()
. के साथ मूल तार प्राप्त कर सकते हैं :to_char(mon, 'Month') AS ea_month to_char(mon, 'YYYY') AS ea_year
दुर्भाग्यपूर्ण डिजाइन के साथ अटके रहने पर, यह काम करेगा:
SELECT ea_month, id, amount, ea_year, circle_id
, sum(amount) OVER (PARTITION BY circle_id ORDER BY mon) AS cum_amt
FROM (SELECT *, to_date(ea_year || ea_month, 'YYYYMonth') AS mon FROM tbl)
ORDER BY circle_id, mon;