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

किसी दिए गए मानदंड को पूरा करने वाले लगातार दिनों के समूह बनाना

इस उत्तर में, मैं मान लूंगा कि "आईडी" फ़ील्ड बढ़ती हुई तारीख के अनुसार क्रमागत रूप से पंक्तियों को क्रमांकित करता है, जैसे कि यह उदाहरण डेटा में करता है। (ऐसा कॉलम मौजूद नहीं होने पर बनाया जा सकता है)।

यह यहां वर्णित तकनीक का एक उदाहरण है। और यहां

1) आसन्न "आईडी" मानों पर स्वयं तालिका में शामिल हों। यह आसन्न पंक्तियों को जोड़ता है। उन पंक्तियों का चयन करें जहां "आवंटन" फ़ील्ड बदल गया है। परिणाम को एक अस्थायी तालिका में संग्रहीत करें, साथ ही एक चालू अनुक्रमणिका भी रखें।

SET @idx = 0;
CREATE TEMPORARY TABLE boundaries
SELECT
   (@idx := @idx + 1) AS idx,
   a1.date AS prev_end,
   a2.date AS next_start,
   a1.allocation as allocation
FROM allocations a1
JOIN allocations a2
ON (a2.id = a1.id + 1)
WHERE a1.allocation != a2.allocation;

यह आपको प्रत्येक पंक्ति में "पिछली अवधि का अंत", "अगली अवधि की शुरुआत", और "पिछली अवधि में 'आवंटन' का मान" वाली तालिका देता है:

+------+------------+------------+------------+
| idx  | prev_end   | next_start | allocation |
+------+------------+------------+------------+
|    1 | 2012-01-01 | 2012-01-02 |          0 |
|    2 | 2012-01-02 | 2012-01-03 |          2 |
|    3 | 2012-01-05 | 2012-01-06 |          0 |
+------+------------+------------+------------+

2) हमें एक ही पंक्ति में प्रत्येक अवधि की शुरुआत और समाप्ति की आवश्यकता है, इसलिए हमें आसन्न पंक्तियों को फिर से संयोजित करने की आवश्यकता है। boundaries . जैसी दूसरी अस्थायी तालिका बनाकर ऐसा करें लेकिन एक idx . होना फ़ील्ड 1 बड़ा:

+------+------------+------------+
| idx  | prev_end   | next_start |
+------+------------+------------+
|    2 | 2012-01-01 | 2012-01-02 |
|    3 | 2012-01-02 | 2012-01-03 |
|    4 | 2012-01-05 | 2012-01-06 |
+------+------------+------------+

अब idx . में शामिल हों फ़ील्ड और हमें उत्तर मिलता है:

SELECT
  boundaries2.next_start AS start,
  boundaries.prev_end AS end,
  allocation
FROM boundaries
JOIN boundaries2
USING(idx);

+------------+------------+------------+
| start      | end        | allocation |
+------------+------------+------------+
| 2012-01-02 | 2012-01-02 |          2 |
| 2012-01-03 | 2012-01-05 |          0 |
+------------+------------+------------+

** ध्यान दें कि यह उत्तर "आंतरिक" अवधियों को सही ढंग से प्राप्त करता है लेकिन दो "किनारे" अवधियों को याद करता है जहां शुरुआत में आवंटन =0 और अंत में आवंटन =5 होता है। उन्हें UNION . का उपयोग करके खींचा जा सकता है खंड लेकिन मैं उस जटिलता के बिना मूल विचार प्रस्तुत करना चाहता था।



  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. SQL संग्रहीत कार्यविधि निष्पादित करें और परिणामों को संसाधित करें

  3. घातक त्रुटि:अपरिभाषित फ़ंक्शन पर कॉल करें sqlsrv_connect ()

  4. एसक्यूएल में कॉलम में पंक्तियों को स्थानांतरित करें

  5. 64 बिट पैकेज में 32 बिट एसएसआईएस पैकेज कैसे निष्पादित करें?