2011-01-24 14 views
6

के बीच पंक्तियों का चयन करें, मैं समय या समय अवधि के विशिष्ट समय के बीच पंक्तियों की कुल संख्या प्राप्त करने का प्रयास कर रहा हूं। मूल रूप से, के निम्न तालिका मान लीजिए:mysql समय अवधि

CREATE TABLE IF NOT EXISTS `downloads` (
`id` int(7) NOT NULL AUTO_INCREMENT, 
`stuff_id` int(7) NOT NULL, 
`user_id` int(7) NOT NULL, 
`dl_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, 
PRIMARY KEY (`id`) 
) ENGINE=MyISAM DEFAULT CHARSET=latin1; 

और इस तालिका हर बार किसी के कुछ डाउनलोड करता भर जाता है।

तो मुझे वास्तव में क्या चाहिए जो उपयोगकर्ताओं (user_id) की एक सूची प्राप्त करने के लिए है, उदाहरण के लिए, उदाहरण के लिए 24 घंटे के उदाहरण के लिए 100 डाउनलोड उदाहरण से अधिक बना दिया है। पिछले 24 घंटों में नहीं, लेकिन उस सटीक अवधि में, भले ही यह पिछले साल क्रिसमस के दौरान रहा हो) =

कोई भी विचार बिल्कुल?

+0

कि क्वेरी, "अवधि की शुरुआत" के रूप में एक टाइमस्टैम्प स्वीकार "की अवधि के अंत" की गणना करने और सभी उपयोगकर्ताओं को इस अवधि में डाउनलोड की राशि को पार कर सूची चाहिए, या क्या उन सभी उपयोगकर्ताओं को सूचीबद्ध करना चाहिए जिन्होंने कभी 24 घंटों की सीमा में एक्स डाउनलोड को पार किया हो? –

+0

@ पैट्रिक कोई शुरुआत नहीं और न ही अंत अवधि ... केवल उन सभी उपयोगकर्ताओं को सूचीबद्ध करें जो वाई में एक्स डाउनलोड को पार करते हैं (एक समय अवधि जो 24 घंटे से कुछ अलग हो सकती है) समय सीमा – eduardev

+0

मैं एक (संभव) समाधान के बारे में सोच रहा था। यदि आप अभी भी रुचि रखते हैं, तो मैं इसे काम करूँगा और इसे यहां पोस्ट करूंगा, लेकिन इसका नकारात्मक हिस्सा होगा: कल्पना कीजिए कि मैं केवल एक घंटे में 100 डाउनलोड करता हूं, फिर कई अवधि होगी जिसमें मैं सीमा से अधिक हो जाऊंगा। पूर्व .: आज 8 और 9 बजे के बीच 100 डाउनलोड। कल सुबह 9 बजे तक 9 बजे = 100 डाउनलोड। कल सुबह 10 बजे तक 10 पूर्वाह्न = 100 डाउनलोड। कल सुबह 11 बजे तक 11 पूर्वाह्न = 100 डाउनलोड। जारी रखने के लिए ... –

उत्तर

6

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

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

प्रश्न के बारे में सोचकर मैं दो अलग-अलग दृष्टिकोणों पर आया।

उनमें से एक को पहले से ही अन्य उत्तरों में निपटाया गया है, यह समय पर एक विशिष्ट बिंदु से शुरू होता है, इस समय शुरू होने वाले अंतराल को देखता है और फिर तत्काल अवधि के अंतराल को देखता है। यह स्पष्ट, समझने योग्य परिणामों की ओर जाता है और शायद यह आवश्यक होगा (उदा। उपयोगकर्ता प्रति कैलेंडर दिन 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-' के बीच 24 घंटे अंतराल (या किसी अन्य अवधि के अंतराल) की अनंत संख्या (गणितीय) है। 01-25 23: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) 
+0

बहुत अच्छी चीजें वहाँ! दोनों विचारों पर प्रदर्शन के बारे में निश्चित नहीं है, वैसे भी, मुख्य उद्देश्य में कोई भी संभावित "24h" अवधि नहीं है। पूर्णता के लिए मैंने इस पर स्वीकृत उत्तर बदल दिया है। – eduardev

2

यह user_id की एक सूची है जो 1 दिन के किसी भी अवधि के दौरान 100 से अधिक डाउनलोड कर दिया है रिटर्न:

SELECT user_id, count(user_id) as downloads_count, DATE(dl_date) 
FROM downloads 
GROUP BY user_id, DATE(dl_date) 
HAVING count(user_id) > 100; 
+0

तिथि के अनुसार दिलचस्प समूह 1 दिन पूरा करेगा, मैं आपको उपयोगी पोट दूंगा यदि मैं कर सकता, वैसे भी कहता हूं कि अवधि पूरे दिन से अलग होगी, उदाहरण के लिए एक सप्ताह या कुछ अधिक जटिल 8 घंटों ... काफी मुश्किल है? मैं इसे संभवतः स्वीकार करूँगा क्योंकि यह अभी के लिए करेगा! धन्यवाद – eduardev

+1

अन्य अवधि के लिए आप समय की अवधि के लिए गोलाकार टाइमस्टैम्प द्वारा समूहित कर सकते हैं: 'उपयोगकर्ता द्वारा आईडी, unix_timestamp (dl_date) - (unix_timestamp (dl_date)% 3600) '(1 घंटा) – arnaud576875

+0

स्पॉट ऑन, बहुत धन्यवाद – eduardev

0

फिर आप user_id पर एक के बीच, समूह का उपयोग कर दो दिनांक मानों पर फ़िल्टर करना चाहते हैं, और समूहित परिणामों को फ़िल्टर करने के लिए हैविंग का उपयोग करें।

तीन पैरामीटर, --Date1--, --Date2--, और --Threshhold--

select user_id 
    , count(*) 
    from downloads 
where dl_date between --Date1-- and --Date2-- 
group by user_id 
having count(*) > --Threshhold-- 
+0

विचार के लिए धन्यवाद लेकिन, अच्छी तरह से कोई प्रारंभ या समाप्ति दिनांक मूल्य नहीं हैं ... ऊपर पैट्रिक Echterbruch देखें! – eduardev

1

आप इस तरह की अवधि, जिसमें 24 घंटे से कम या बराबर है, तो:

SET @period_start='2010-10-10 06:00:00'; 
SET @period_end='2010-10-11 05:59:59'; 
तो

,

SELECT user_id, COUNT(id) AS num 
FROM downloads WHERE dl_date>= @period_start AND dl_date<= @period_end 
GROUP BY user_id HAVING num> 100; 

लेकिन आप इस तरह की एक अवधि है, जो 24 घंटों से अधिक है अगर:

SET @period_start='2010-10-10 06:00:00'; 
SET @period_end='2011-09-17 13:15:12'; 

आप अपने डाउनलोड नंबर की गणना कैसे करना चाहते हैं? क्या यह @period_end, या @period_start से 24h हिस्सों में है। या आप बस सबसे हाल ही में 24h हिस्सा चाहते हैं?

संबंधित मुद्दे