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

लगातार x दिनों के लिए जाँच करें - डेटाबेस में दिए गए टाइमस्टैम्प

आप एक चर के साथ संयोजन के रूप में एक स्थानांतरित स्व-बाहरी-जुड़ने का उपयोग करके इसे पूरा कर सकते हैं। यह समाधान देखें:

SELECT IF(COUNT(1) > 0, 1, 0) AS has_consec
FROM
(
    SELECT *
    FROM
    (
        SELECT IF(b.login_date IS NULL, @val:[email protected]+1, @val) AS consec_set
        FROM tbl a
        CROSS JOIN (SELECT @val:=0) var_init
        LEFT JOIN tbl b ON 
            a.user_id = b.user_id AND
            a.login_date = b.login_date + INTERVAL 1 DAY
        WHERE a.user_id = 1
    ) a
    GROUP BY a.consec_set
    HAVING COUNT(1) >= 30
) a

यह या तो 1 लौटाएगा या एक 0 इस आधार पर कि क्या उपयोगकर्ता ने किसी भी समय . पर लगातार 30 दिनों या उससे अधिक समय तक लॉग इन किया है पिछले।

इस क्वेरी का खामियाजा वास्तव में पहले उप-चयन में है। आइए करीब से देखें ताकि हम बेहतर ढंग से समझ सकें कि यह कैसे काम करता है:

निम्न उदाहरण डेटा सेट के साथ:

CREATE TABLE tbl (
  user_id INT,
  login_date DATE
);

INSERT INTO tbl VALUES
(1, '2012-04-01'),  (2, '2012-04-02'),
(1, '2012-04-25'),  (2, '2012-04-03'),
(1, '2012-05-03'),  (2, '2012-04-04'),
(1, '2012-05-04'),  (2, '2012-05-04'),
(1, '2012-05-05'),  (2, '2012-05-06'),
(1, '2012-05-06'),  (2, '2012-05-08'),
(1, '2012-05-07'),  (2, '2012-05-09'),
(1, '2012-05-09'),  (2, '2012-05-11'),
(1, '2012-05-10'),  (2, '2012-05-17'),
(1, '2012-05-11'),  (2, '2012-05-18'),
(1, '2012-05-12'),  (2, '2012-05-19'),
(1, '2012-05-16'),  (2, '2012-05-20'),
(1, '2012-05-19'),  (2, '2012-05-21'),
(1, '2012-05-20'),  (2, '2012-05-22'),
(1, '2012-05-21'),  (2, '2012-05-25'),
(1, '2012-05-22'),  (2, '2012-05-26'),
(1, '2012-05-25'),  (2, '2012-05-27'),
                    (2, '2012-05-28'),
                    (2, '2012-05-29'),
                    (2, '2012-05-30'),
                    (2, '2012-05-31'),
                    (2, '2012-06-01'),
                    (2, '2012-06-02');

यह प्रश्न:

SELECT a.*, b.*, IF(b.login_date IS NULL, @val:[email protected]+1, @val) AS consec_set
FROM tbl a
CROSS JOIN (SELECT @val:=0) var_init
LEFT JOIN tbl b ON 
    a.user_id = b.user_id AND
    a.login_date = b.login_date + INTERVAL 1 DAY
WHERE a.user_id = 1

उत्पादन करेंगे:

जैसा कि आप देख सकते हैं, हम जो कर रहे हैं वह है स्थानांतरित करना +1 दिन तक तालिका में शामिल हुआ। प्रत्येक दिन के लिए जो पहले दिन के साथ लगातार नहीं है, एक NULL मान लेफ्ट जॉइन द्वारा उत्पन्न होता है।

अब जबकि हम जानते हैं जहां लगातार दिन होते हैं, हम प्रत्येक सेट . में अंतर करने के लिए एक चर का उपयोग कर सकते हैं यह पता लगाकर कि शिफ्ट की गई तालिका की पंक्तियाँ NULL हैं या नहीं, लगातार दिनों तक . अगर वे NULL हैं , दिन लगातार नहीं होते हैं, इसलिए केवल चर बढ़ाएँ। यदि वे NOT NULL , फिर वेरिएबल में वृद्धि न करें:

जब हम लगातार दिनों के प्रत्येक सेट को वृद्धिशील चर के साथ अलग कर देते हैं, तो यह प्रत्येक "सेट" द्वारा समूहीकृत करने का एक साधारण मामला है (जैसा कि consec_set में परिभाषित किया गया है) कॉलम) और HAVING . का उपयोग कर रहे हैं निर्दिष्ट लगातार दिनों से कम वाले किसी भी सेट को फ़िल्टर करने के लिए (आपके उदाहरण में 30):

फिर अंत में, हम कि को लपेटते हैं क्वेरी करें और केवल उन सेटों की संख्या गिनें जिनमें लगातार 30 या अधिक दिन थे। यदि इनमें से एक या अधिक सेट थे, तो 1 लौटाएं , अन्यथा 0 return लौटाएं ।

एक SQLFiddle चरण-दर-चरण डेमो देखें



  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 में UNHEX () फ़ंक्शन कैसे काम करता है

  2. MySQL:GROUP_CONCAT मानों को क्रमबद्ध करें

  3. इसका क्या अर्थ है जब MySQL डेटा भेज रहा है?

  4. MySQL में दो कॉलम के प्रतिशत की गणना कैसे करें

  5. #1139 - regexp . से त्रुटि 'पुनरावृत्ति-संचालक संकार्य अमान्य' मिला