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

एक ही तालिका में दो दिनांक सीमाओं की तुलना करना

IBM Informix Dynamic Server 11.50.FC6 का उपयोग करते हुए, मैं आपके लिए आवश्यक परिणाम प्राप्त करने के लिए इस SQL ​​​​अनुक्रम का उपयोग कर सकता हूं:

सेटअप

CREATE TABLE sales
(
    id       INTEGER NOT NULL,
    id_store INTEGER NOT NULL,
    date     DATE NOT NULL,
    total    DECIMAL(10,2) NOT NULL
);

INSERT INTO sales VALUES( 1, 1, '2010-01-01', 500.00);
INSERT INTO sales VALUES( 2, 1, '2010-01-02', 185.00);
INSERT INTO sales VALUES( 3, 1, '2010-01-03', 135.00);
INSERT INTO sales VALUES( 4, 1, '2009-01-01', 165.00);
INSERT INTO sales VALUES( 5, 1, '2009-01-02', 175.00);
INSERT INTO sales VALUES( 6, 5, '2010-01-01', 130.00);
INSERT INTO sales VALUES( 7, 5, '2010-01-02', 135.00);
INSERT INTO sales VALUES( 8, 5, '2010-01-03', 130.00);
INSERT INTO sales VALUES( 9, 6, '2010-01-01', 100.00);
INSERT INTO sales VALUES(10, 6, '2010-01-02',  12.00);
INSERT INTO sales VALUES(11, 6, '2010-01-03',  85.00);
INSERT INTO sales VALUES(12, 6, '2009-01-01', 135.00);
INSERT INTO sales VALUES(13, 6, '2009-01-02', 400.00);
INSERT INTO sales VALUES(14, 6, '2009-01-07',  21.00);
INSERT INTO sales VALUES(15, 6, '2009-01-08',  45.00);
INSERT INTO sales VALUES(16, 8, '2009-01-09', 123.00);
INSERT INTO sales VALUES(17, 8, '2009-01-10', 581.00);

क्वेरी

SELECT *
  FROM (SELECT s1.id AS s1id,
               NVL(s1.id_store, s2.id_store) AS s1store,
               NVL(s1.date, MDY(MONTH(s2.date), DAY(s2.date),
                                YEAR(s2.date)+1)) AS s1date,
               s1.total AS s1total,
               s2.id AS s2id,
               NVL(s2.id_store, s1.id_store) AS s2store,
               NVL(s2.date, MDY(MONTH(s1.date), DAY(s1.date),
                                YEAR(s1.date)-1)) AS s2date,
               s2.total AS s2total
          FROM sales AS s1 FULL JOIN sales AS s2
            ON s1.id_store = s2.id_store
           AND s1.date BETWEEN '2010-01-01' AND '2010-01-10'
           AND s2.date BETWEEN '2009-01-01' AND '2009-01-10'
           AND DAY(s1.date)   = DAY(s2.date)
           AND MONTH(s1.date) = MONTH(s2.date)
       ) AS s3
 WHERE s1_date BETWEEN '2010-01-01' AND '2010-01-10'
   AND s2_date BETWEEN '2009-01-01' AND '2009-01-10'
 ORDER BY s1_id_store ASC, s1_date ASC;

परिणाम

s1id s1store  s1date     s1total  s2id s2store  s2date     s2total
 1       1    2010-01-01  500.00   4       1    2009-01-01  165.00
 2       1    2010-01-02  185.00   5       1    2009-01-02  175.00
 3       1    2010-01-03  135.00           1    2009-01-03             
 6       5    2010-01-01  130.00           5    2009-01-01             
 7       5    2010-01-02  135.00           5    2009-01-02             
 8       5    2010-01-03  130.00           5    2009-01-03             
 9       6    2010-01-01  100.00  12       6    2009-01-01  135.00
10       6    2010-01-02   12.00  13       6    2009-01-02  400.00
11       6    2010-01-03   85.00           6    2009-01-03             
         6    2010-01-07          14       6    2009-01-07   21.00
         6    2010-01-08          15       6    2009-01-08   45.00
         8    2010-01-09          16       8    2009-01-09  123.00
         8    2010-01-10          17       8    2009-01-10  581.00

स्पष्टीकरण

इस 'अधिकार' को प्राप्त करने के लिए उचित मात्रा में प्रयोग करना पड़ा। इनफॉर्मिक्स में एक DATE कंस्ट्रक्टर फ़ंक्शन MDY() है जो तीन पूर्णांक तर्क लेता है:महीना, दिन और वर्ष (नाम निमोनिक है)। इसके तीन विश्लेषण कार्य भी हैं:DAY(), MONTH() और YEAR() जो दिनांक तर्क के दिन, महीने और वर्ष को लौटाते हैं। पूर्ण जॉइन के साथ आंतरिक क्वेरी आपको बाएं और दाएं दोनों तरफ नल के साथ परिणाम देती है। ON क्लॉज में 5-भाग मानदंड आवश्यक प्रतीत होता है; अन्यथा, बाहरी क्वेरी में मानदंड अधिक जटिल और भ्रमित करने वाला होना चाहिए - यदि इसे बिल्कुल भी काम करने के लिए बनाया जा सकता है। फिर बाहरी चयन में मानदंड सुनिश्चित करते हैं कि सही डेटा चुना गया है। आंतरिक क्वेरी में एनवीएल () अभिव्यक्तियों का एक फायदा यह है कि स्टोर आईडी कॉलम दोनों समान हैं और शून्य नहीं हैं और न ही तारीख कॉलम शून्य है, इसलिए क्लॉज द्वारा ऑर्डर सरल हो सकता है - स्टोर आईडी और किसी भी तारीख कॉलम पर।

इनफॉर्मिक्स में, तारीख के भावों को इस तरह से फिर से काम करना भी संभव होगा:

NVL(s1.date, s2.date + 1 UNITS YEAR)
NVL(s2.date, s1.date - 1 UNITS YEAR)

वास्तव में उस संकेतन के साथ पर्दे के पीछे कई प्रकार के रूपांतरण चल रहे हैं, लेकिन यह आपको वही परिणाम देता है और अतिरिक्त गणना शायद इतना महत्वपूर्ण नहीं है।

Informix में वेटिंग में भी गड़बड़ी है; आप 29 फरवरी को या उससे 1 वर्ष जोड़ या घटा नहीं सकते - क्योंकि अगले या पिछले वर्ष में 29 फरवरी नहीं है। आपको अपने डेटा से सावधान रहने की आवश्यकता होगी; यदि आप नहीं हैं, तो आप 2008-02-29 के डेटा की 2009-02-28 से तुलना कर सकते हैं (साथ ही 2008-02-28 के डेटा की 2009-02-28 से तुलना कर सकते हैं)। 'दोहरी प्रविष्टि बहीखाता पद्धति' नामक एक प्रक्रिया है, लेकिन इसका मतलब यह नहीं है, और यदि '2008-02-29 प्लस 1 वर्ष' 2009-02-28 है, तो आपकी गणना भ्रमित हो सकती है। Informix एक त्रुटि उत्पन्न करता है; यह बहुत अधिक सहायक नहीं है। आप एक संग्रहीत कार्यविधि को कोड कर सकते हैं, संभवत:2008-02-29 प्लस 1 वर्ष के लिए NULL वापस करने के लिए, क्योंकि इसकी बिक्री की तुलना करने के लिए कोई तारीख नहीं है।

आपको दिनांक अंकगणित को MySQL में काफी आसानी से अनुकूलित करने में सक्षम होना चाहिए; शेष कोड को बदलने की आवश्यकता नहीं है।



  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 / MariaDB सीखें - भाग 1

  2. mysql प्रक्रियाओं में त्रुटि त्रुटि 1304 और त्रुटि 1305

  3. लार्वेल 5 में अक्षांश और देशांतर से अन्य जुड़ने के साथ प्राप्त करें

  4. पायथन में, यदि मेरे पास यूनिक्स टाइमस्टैम्प है, तो मैं इसे MySQL डेटाटाइम फ़ील्ड में कैसे सम्मिलित करूं?

  5. कैसे (चुपचाप) 32 और 64 बिट विंडोज़ पर MySQL की स्थापना रद्द करें