CROSS JOIN के साथ रनिंग टोटल
MySQL में यूजर-डिफाइंड वेरिएबल (@var) और CROSS JOIN का उपयोग करके प्रत्येक पंक्ति का मान पिछली पंक्तियों के योग के साथ दिखाएं (क्यूमुलेटिव सम)।
उदाहरण: टेबल बनाना और डेटा इन्सर्ट करना
mysql> CREATE TABLE DemoTable(Value INT); Query OK, 0 rows affected (1.79 sec)
रिकॉर्ड्स इन्सर्ट करना
mysql> INSERT INTO DemoTable VALUES(50),(20),(30); Query OK, 3 rows affected (...)
सभी रिकॉर्ड्स देखना
mysql> SELECT * FROM DemoTable;
+-------+ | Value | +-------+ | 50 | | 20 | | 30 | +-------+ 3 rows in set (0.00 sec)
CROSS JOIN के साथ रनिंग टोटल क्वेरी
mysql> SELECT t.Value,
(@s := @s + t.Value) AS RunningTotal
FROM DemoTable t
CROSS JOIN (SELECT @s := 0) p
ORDER BY t.Value;
परिणाम (Value के आरोही क्रम में)
+-------+--------------+ | Value | RunningTotal | +-------+--------------+ | 20 | 20 | | 30 | 50 | | 50 | 100 | +-------+--------------+ 3 rows in set (0.07 sec)
क्वेरी व्याख्या
CROSS JOIN (SELECT @s := 0) p- वेरिएबल@sको 0 से आरंभ करता हैORDER BY t.Value- क्रम निर्धारित करता है (महत्वपूर्ण!)@s := @s + t.Value- प्रत्येक पंक्ति के लिए वेरिएबल अपडेट करता है और नया मान लौटाता है
महत्वपूर्ण: ORDER BY आवश्यक है
बिना ORDER BY के पंक्तियों का क्रम अनिर्धारित है, जिससे गलत रनिंग टोटल मिलेगा।
मूल इन्सर्ट क्रम बनाए रखने के लिए
यदि टेबल में ऑटो-इन्क्रीमेंट ID है:
SELECT t.Value, (@s := @s + t.Value) AS RunningTotal FROM DemoTable t CROSS JOIN (SELECT @s := 0) p ORDER BY t.Id; -- इन्सर्ट क्रम
विंडो फंक्शन (MySQL 8.0+ अनुशंसित)
SELECT Value,
SUM(Value) OVER (ORDER BY Value ROWS UNBOUNDED PRECEDING) AS RunningTotal
FROM DemoTable;
लाभ
- कोई वेरिएबल आरंभिकरण नहीं
- निर्धारित, मानक SQL
- बेहतर ऑप्टिमाइज़ेशन
PARTITION BYसपोर्ट:SUM(Value) OVER (PARTITION BY Category ORDER BY Date)ROWS BETWEENफ्रेम क्लॉज सपोर्ट
वेरिएबल दृष्टिकोण की सीमाएं
- नॉन-डिटरमिनिस्टिक (ऑप्टिमाइज़र क्रम बदल सकता है)
- रिप्लिकेशन में असुरक्षित (स्टेटमेंट-आधारित)
- क्वेरी कैश के साथ काम नहीं करता
- जटिल क्वेरीज में अप्रत्याशित व्यवहार
अन्य विंडो फंक्शन उदाहरण
-- मूविंग एवरेज (3 पंक्तियों की विंडो) AVG(Value) OVER (ORDER BY Id ROWS BETWEEN 2 PRECEDING AND CURRENT ROW) -- रैंकिंग RANK() OVER (ORDER BY Value DESC) -- पर्सेंटाइल PERCENT_RANK() OVER (ORDER BY Value)