Mysql
 sql >> डेटाबेस >  >> RDS >> Mysql

Mysql में पंक्तियों के एक सेट पर संचयी योग

अपडेट करें

MySQL 8.0 "विंडो फ़ंक्शंस", SQL सर्वर "विंडो फ़ंक्शंस" के समतुल्य कार्यक्षमता का परिचय देता है (Transact-SQL OVER द्वारा प्रदान किए गए विभाजन और क्रम के साथ) सिंटैक्स), और Oracle "विश्लेषणात्मक कार्य"।

MySQL संदर्भ मैनुअल 12.21 विंडो फ़ंक्शंस https://dev.mysql .com/doc/refman/8.0/hi/window-functions.html

यहां दिया गया उत्तर 8.0 से पहले के MySQL संस्करणों के लिए एक दृष्टिकोण है।

मूल उत्तर

MySQL अन्य डीबीएमएस (जैसे ओरेकल या एसक्यूएल सर्वर) में उपलब्ध विश्लेषणात्मक कार्यों की तरह चल रहे "संचयी योग" प्राप्त करने के लिए उपयोग किए जाने वाले प्रकार विश्लेषणात्मक फ़ंक्शन प्रदान नहीं करता है।

लेकिन, MySQL का उपयोग करके कुछ विश्लेषणात्मक कार्यों का अनुकरण करना संभव है।

दो व्यावहारिक दृष्टिकोण (कम से कम) हैं:

उप-योग प्राप्त करने के लिए एक सहसंबद्ध उपश्रेणी का उपयोग करना है। यह दृष्टिकोण बड़े सेटों पर महंगा हो सकता है, और जटिल हो सकता है यदि बाहरी क्वेरी पर विधेय जटिल हैं। यह वास्तव में इस बात पर निर्भर करता है कि "एकाधिक तालिकाओं पर एकाधिक जुड़ना" कितना जटिल है। (दुर्भाग्य से, MySQL भी सीटीई का समर्थन नहीं करता है।)

अन्य दृष्टिकोण कुछ नियंत्रण विराम प्रसंस्करण करने के लिए MySQL उपयोगकर्ता चर का उपयोग करना है। यहां "ट्रिक" आपकी क्वेरी से सॉर्ट किए गए परिणामों के लिए है (एक ORDER BY का उपयोग करके) और फिर अपनी क्वेरी को किसी अन्य क्वेरी में लपेटना।

मैं बाद के दृष्टिकोण का एक उदाहरण दूंगा।

MySQL द्वारा संचालन करने के क्रम के कारण, cumulative_total कॉलम की गणना id . से मान से पहले की जानी चाहिए और day वर्तमान पंक्ति से उपयोगकर्ता चर में सहेजे जाते हैं। इस कॉलम को पहले रखना सबसे आसान है।

इनलाइन व्यू को i (नीचे दी गई क्वेरी में) के रूप में उपनामित किया गया है, बस उपयोगकर्ता चर को प्रारंभ करने के लिए है, बस अगर ये पहले से ही सत्र में सेट हैं। यदि उनके पास पहले से ही मान निर्दिष्ट हैं, तो हम उनके वर्तमान मूल्यों को अनदेखा करना चाहते हैं, और ऐसा करने का सबसे आसान तरीका उन्हें प्रारंभ करना है।

आपकी मूल क्वेरी कोष्ठक में लिपटी हुई है, और उसे एक उपनाम दिया गया है, c नीचे दिए गए उदाहरण में। आपकी मूल क्वेरी में एकमात्र परिवर्तन ORDER BY क्लॉज का जोड़ है, इसलिए हम सुनिश्चित हो सकते हैं कि हम क्वेरी से पंक्तियों को क्रम से संसाधित करते हैं।

बाहरी चयन जाँचता है कि क्या id और day वर्तमान पंक्ति से मान पिछली पंक्ति से "मिलान" करें। अगर वे ऐसा करते हैं, तो हम amount जोड़ते हैं वर्तमान पंक्ति से संचयी उप-योग तक। यदि वे मेल नहीं खाते हैं, तो हम संचयी उप-योग को शून्य पर रीसेट करते हैं, और वर्तमान पंक्ति से राशि जोड़ते हैं (या, अधिक सरलता से, केवल वर्तमान पंक्ति से राशि असाइन करें)।

संचयी कुल की गणना करने के बाद, हम id . को सहेजते हैं और day वर्तमान पंक्ति से उपयोगकर्ता चर में मान, इसलिए जब हम अगली पंक्ति को संसाधित करते हैं तो वे उपलब्ध होते हैं।

उदाहरण के लिए:

SELECT IF(@prev_id = c.id AND @prev_day = c.day
         ,@cumtotal := @cumtotal + c.amount
         ,@cumtotal := c.amount) AS cumulative_total
     , @prev_id  := c.id  AS `id`
     , @prev_day := c.day AS `day`
     , c.hr
     , c.amount AS `amount'
  FROM ( SELECT @prev_id  := NULL
              , @prev_day := NULL
              , @subtotal := 0
       ) i
  JOIN (

         select id, day, hr, amount from
         ( //multiple joins on multiple tables)a
         left join
         (//unions on multiple tables)b
         on a.id=b.id

         ORDER BY 1,2,3
       ) c

यदि अंतिम कॉलम के रूप में संचयी कुल के साथ कॉलम को एक अलग क्रम में वापस करना आवश्यक है, तो एक विकल्प है कि पूरे स्टेटमेंट को माता-पिता के सेट में लपेटना है, और उस क्वेरी को इनलाइन व्यू के रूप में उपयोग करना है:

SELECT d.id
     , d.day
     , d.hr
     , d.amount
     , d.cumulative_total
FROM (
       // query from above
     ) d


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. नेस्टेड क्लासेस - CustomRowMapper !! अब कोई समस्या नहीं !! - भाग 2

  2. nth शब्द कैसे निकालें और MySQL स्ट्रिंग में शब्द घटनाओं की गणना कैसे करें?

  3. त्रुटि 1452:चाइल्ड पंक्ति को जोड़ या अद्यतन नहीं कर सकता:एक विदेशी कुंजी बाधा विफल हो जाती है

  4. MySQL क्विक टिप:DROP USER कमांड का उपयोग करना

  5. mysqli_stmt ::bind_result ():बाइंड चर की संख्या तैयार कथन में फ़ील्ड की संख्या से मेल नहीं खाती