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

mysql समय अवधि के बीच पंक्तियों की संख्या का चयन करें

ठीक है, मुझे एहसास हुआ कि मुझे थोड़ी देर हो गई है, लेकिन मैं वैसे भी अपना उत्तर पोस्ट करना चाहता था :-)

आपको जो चाहिए वह सबक्वेरी का उपयोग करके किया जा सकता है, लेकिन इसे एक बड़ी टेबल पर पूरा करने में उम्र लग सकती है...

प्रश्न के बारे में सोचते हुए मैं दो अलग-अलग तरीकों से आया।

उनमें से एक को पहले से ही अन्य उत्तरों में निपटाया जा चुका है, यह समय में एक विशिष्ट बिंदु से शुरू करके काम करता है, इस समय शुरू होने वाले अंतराल को देखता है और फिर बराबर अवधि के अंतराल को तुरंत देखता है। इससे स्पष्ट, समझने योग्य परिणाम मिलते हैं और संभवत:यही आवश्यक होगा (उदाहरण के लिए उपयोगकर्ता को प्रति कैलेंडर दिन में 100 डाउनलोड से अधिक नहीं होना चाहिए)। हालांकि यह उन स्थितियों को पूरी तरह से याद करेगा जिनमें एक उपयोगकर्ता मध्यरात्रि से पहले घंटे के दौरान 99 और नए दिन के पहले घंटे में 99 डाउनलोड करता है।

इसलिए यदि आवश्यक परिणाम "शीर्ष दस डाउनलोडर सूची" से अधिक है, तो यह दूसरा तरीका है। यहां परिणाम पहली नज़र में समझने योग्य नहीं हो सकते हैं, क्योंकि एक एकल डाउनलोड कई अंतरालों में गिना जा सकता है। ऐसा इसलिए है क्योंकि अंतराल ओवरलैप करेंगे (और करने की आवश्यकता है)।

यहाँ मेरा सेटअप है। मैंने आपके कथन से तालिका बनाई है और दो अनुक्रमणिकाएँ जोड़ी हैं:

CREATE INDEX downloads_timestamp on downloads (dl_date);
CREATE INDEX downloads_user_id on downloads (user_id);

डेटा जो मैंने तालिका में डाला है:

SELECT * FROM downloads;
+----+----------+---------+---------------------+
| id | stuff_id | user_id | dl_date             |
+----+----------+---------+---------------------+
|  1 |        1 |       1 | 2011-01-24 09:00:00 |
|  2 |        1 |       1 | 2011-01-24 09:30:00 |
|  3 |        1 |       1 | 2011-01-24 09:35:00 |
|  4 |        1 |       1 | 2011-01-24 10:00:00 |
|  5 |        1 |       1 | 2011-01-24 11:00:00 |
|  6 |        1 |       1 | 2011-01-24 11:15:00 |
|  7 |        1 |       1 | 2011-01-25 09:15:00 |
|  8 |        1 |       1 | 2011-01-25 09:30:00 |
|  9 |        1 |       1 | 2011-01-25 09:45:00 |
| 10 |        1 |       2 | 2011-01-24 08:00:00 |
| 11 |        1 |       2 | 2011-01-24 12:00:00 |
| 12 |        1 |       2 | 2011-01-24 12:01:00 |
| 13 |        1 |       2 | 2011-01-24 12:02:00 |
| 14 |        1 |       2 | 2011-01-24 12:03:00 |
| 15 |        1 |       2 | 2011-01-24 12:00:00 |
| 16 |        1 |       2 | 2011-01-24 12:04:00 |
| 17 |        1 |       2 | 2011-01-24 12:05:00 |
| 18 |        1 |       2 | 2011-01-24 12:06:00 |
| 19 |        1 |       2 | 2011-01-24 12:07:00 |
| 20 |        1 |       2 | 2011-01-24 12:08:00 |
| 21 |        1 |       2 | 2011-01-24 12:09:00 |
| 22 |        1 |       2 | 2011-01-24 12:10:00 |
| 23 |        1 |       2 | 2011-01-25 14:00:00 |
| 24 |        1 |       2 | 2011-01-25 14:12:00 |
| 25 |        1 |       2 | 2011-01-25 14:25:00 |
+----+----------+---------+---------------------+
25 rows in set (0.00 sec)

जैसा कि आप देख सकते हैं, सभी डाउनलोड कल या आज हुए और दो अलग-अलग उपयोगकर्ताओं द्वारा निष्पादित किए गए।

अब, हमें जो ध्यान रखना है वह निम्नलिखित है:'2011-01-24 0:00' और '2011-01-25 23 के बीच (गणितीय रूप से) 24 घंटे के अंतराल (या किसी अन्य अवधि के अंतराल) की अनंत संख्या है। :59:59'। लेकिन चूंकि सर्वर की सटीकता एक सेकंड है, यह 86,400 अंतराल तक उबलता है:

First interval:  2011-01-24 0:00:00 -> 2011-01-25 0:00:00
Second interval: 2011-01-24 0:00:01 -> 2011-01-25 0:00:01
Third interval: 2011-01-24 0:00:02 -> 2011-01-25 0:00:02
   .
   .
   .
86400th interval: 2011-01-24 23:59:59 -> 2011-01-25 23:59:59

इसलिए हम इन सभी अंतरालों पर पुनरावृति करने के लिए एक लूप का उपयोग कर सकते हैं और प्रति उपयोगकर्ता और प्रति अंतराल डाउनलोड की संख्या की गणना कर सकते हैं। बेशक, सभी अंतराल हमारे लिए समान रुचि के नहीं हैं, इसलिए हम तालिका में टाइमस्टैम्प को "अंतराल की शुरुआत" के रूप में उपयोग करके उनमें से कुछ को छोड़ सकते हैं।

निम्नलिखित क्वेरी यही करती है। यह तालिका में प्रत्येक डाउनलोड टाइमस्टैम्प का उपयोग "अंतराल की शुरुआत" के रूप में करता है, अंतराल अवधि जोड़ता है और फिर इस अंतराल के दौरान प्रति उपयोगकर्ता डाउनलोड की संख्या पूछता है।

SET @duration = '24:00:00';
SET @limit = 5;
SELECT * FROM 
    (SELECT t1.user_id, 
            t1.dl_date startOfPeriod, 
            ADDTIME(t1.dl_date,@duration) endOfPeriod, 
           (SELECT COUNT(1) 
            FROM downloads t2 
            WHERE t1.user_id = t2.user_id 
            AND t1.dl_date <= t2.dl_date 
            AND ADDTIME(t1.dl_date,@duration) >= t2.dl_date) count
     FROM downloads t1) t3 
WHERE count > @limit;

ये रहा परिणाम:

+---------+---------------------+---------------------+-------+
| user_id | startOfPeriod       | endOfPeriod         | count |
+---------+---------------------+---------------------+-------+
|       1 | 2011-01-24 09:00:00 | 2011-01-25 09:00:00 |     6 |
|       1 | 2011-01-24 09:30:00 | 2011-01-25 09:30:00 |     7 |
|       1 | 2011-01-24 09:35:00 | 2011-01-25 09:35:00 |     6 |
|       1 | 2011-01-24 10:00:00 | 2011-01-25 10:00:00 |     6 |
|       2 | 2011-01-24 08:00:00 | 2011-01-25 08:00:00 |    13 |
|       2 | 2011-01-24 12:00:00 | 2011-01-25 12:00:00 |    12 |
|       2 | 2011-01-24 12:01:00 | 2011-01-25 12:01:00 |    10 |
|       2 | 2011-01-24 12:02:00 | 2011-01-25 12:02:00 |     9 |
|       2 | 2011-01-24 12:03:00 | 2011-01-25 12:03:00 |     8 |
|       2 | 2011-01-24 12:00:00 | 2011-01-25 12:00:00 |    12 |
|       2 | 2011-01-24 12:04:00 | 2011-01-25 12:04:00 |     7 |
|       2 | 2011-01-24 12:05:00 | 2011-01-25 12:05:00 |     6 |
+---------+---------------------+---------------------+-------+
12 rows in set (0.00 sec)


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. डुप्लिकेट कुंजी सम्मिलित अपवाद को पकड़ें

  2. एकाधिक कॉलम ऑर्डर करें एएससी

  3. SQLAlchemy में ENUM कैसे बनाएं?

  4. एसक्यूएल परिकलित कॉलम के न्यूनतम मूल्य के आधार पर पूरी पंक्ति प्राप्त करें

  5. MySQL:MyISAM से InnoDB में कनवर्ट करने से क्वेरीज़ तेज़ हो जाती हैं...?