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

रोलिंग योग कैसे करें, प्रत्येक पंक्ति में पिछली पंक्तियों का योग शामिल होना चाहिए

विश्लेषणात्मक कार्यों का अनुकरण करने के लिए आप MySQL उपयोगकर्ता चर का उपयोग कर सकते हैं। (कुछ अन्य तरीके भी हैं, जैसे सेमी-जॉइन का उपयोग करना या सहसंबद्ध सबक्वेरी का उपयोग करना। मैं उनके लिए भी समाधान प्रदान कर सकता हूं, अगर आपको लगता है कि वे अधिक उपयुक्त हो सकते हैं।)

"रनिंग टोटल" एनालिटिक फंक्शन का अनुकरण करने के लिए, कुछ इस तरह से प्रयास करें:

SELECT t.user_id
     , t.starttime
     , t.order_number
     , IF(t.order_number IS NOT NULL,
         @tot_dur := 0,
         @tot_dur := @tot_dur + t.visit_duration_seconds) AS tot_dur
  FROM visit t
  JOIN (SELECT @tot_dur := 0) d
 ORDER BY t.user_id, t.start_time

order_number . है या नहीं, इसका परीक्षण करने के लिए यहां "ट्रिक" एक IF फ़ंक्शन का उपयोग करना है शून्य है। जब यह शून्य होता है, तो हम वेरिएबल में अवधि मान जोड़ते हैं, अन्यथा, हम वेरिएबल को शून्य पर सेट करते हैं।

हम एक इनलाइन दृश्य (d . के रूप में उपनामित) का उपयोग करते हैं , यह सुनिश्चित करने के लिए कि @tot_dur चर को शून्य से प्रारंभ किया गया है।

नोट:इस तरह MySQL उपयोगकर्ता चर का उपयोग करने में सावधानी बरतें। ऊपर दिए गए सेलेक्ट स्टेटमेंट में, सेलेक्ट लिस्ट में वेरिएबल्स का असाइनमेंट ORDER BY के बाद होता है, इसलिए हम नियतात्मक व्यवहार प्राप्त कर सकते हैं।

वह क्वेरी user_id में "ब्रेक" को हैंडल नहीं करती है। इसे प्राप्त करने के लिए, हमें पिछली पंक्ति से user_id के मान की आवश्यकता होगी। हम इसे किसी अन्य उपयोगकर्ता चर में संरक्षित कर सकते हैं। संचालन का क्रम नियतात्मक है, और पिछली पंक्ति से user_id को अधिलेखित करने से पहले हमें संचय करने के लिए सावधानी बरतने की आवश्यकता है।

हमें या तो कॉलम को फिर से व्यवस्थित करना होगा ताकि user_id tot_dur के बाद दिखाई दे (या user_id कॉलम की दूसरी कॉपी शामिल करें)

SELECT t.user_id
     , t.starttime
     , t.order_number
     , IF(t.order_number IS NULL,
         @tot_dur := IF(@prev_user_id = t.user_id,@tot_dur,0) + t.visit_duration_seconds,
         @tot_dur := 0
       ) AS tot_dur
     , @prev_user_id := t.user_id AS prev_user_id
  FROM visit t
  JOIN (SELECT @tot_dur := 0, @prev_user_id := NULL) d
 ORDER BY t.user_id, t.start_time

user_id . में दिए गए मान और prev_user_id कॉलम समान हैं। उस "अतिरिक्त" कॉलम को हटाया जा सकता है, या किसी अन्य क्वेरी में क्वेरी (इनलाइन व्यू के रूप में) लपेटकर कॉलम को फिर से व्यवस्थित किया जा सकता है, हालांकि यह एक प्रदर्शन लागत पर आता है:

SELECT v.user_id
     , v.starttime
     , v.order_number
     , v.tot_dur
  FROM (SELECT t.starttime
             , t.order_number
             , IF(t.order_number IS NULL,
                 @tot_dur := IF(@prev_user_id = t.user_id,@tot_dur,0) + t.visit_duration_seconds,
                 @tot_dur := 0
               ) AS tot_dur
             , @prev_user_id := t.user_id AS user_id
          FROM visit t
          JOIN (SELECT @tot_dur := 0, @prev_user_id := NULL) d
         ORDER BY t.user_id, t.start_time
       ) v

वह क्वेरी दर्शाती है कि MySQL के लिए निर्दिष्ट परिणाम को वापस करना संभव है। लेकिन इष्टतम प्रदर्शन के लिए, हम केवल इनलाइन दृश्य में क्वेरी चलाना चाहते हैं (उपनाम v ), और जब पंक्तियों को पुनः प्राप्त किया जाता है, तो क्लाइंट साइड पर कॉलम (पहले user_id कॉलम डालते हुए) के पुन:क्रम को संभालें।

अन्य दो सामान्य दृष्टिकोण एक सेमी-जॉइन का उपयोग कर रहे हैं, और एक सहसंबद्ध सबक्वेरी का उपयोग कर रहे हैं, हालांकि बड़े सेट को संसाधित करते समय ये दृष्टिकोण अधिक संसाधन गहन हो सकते हैं।




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. क्या एक चर को MySQL में संग्रहीत प्रक्रिया कॉल में पास करना संभव है?

  2. MySQL स्थापना

  3. डेटाबेस/एसक्यूएल:देशांतर/अक्षांश डेटा कैसे स्टोर करें?

  4. MySQL के साथ कई टेबल से रैंकिंग लौटाएं

  5. mysql लाने के रिकॉर्ड के साथ एक ईमेल भेजें