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

SQL - पता लगाएं कि क्या कॉलम तिथियों में कम से कम आंशिक रूप से एक तिथि सीमा शामिल है

मुझे लगता है कि इसे अंतराल और द्वीपों . के रूप में नियंत्रित किया जा सकता है संकट। निम्नलिखित इनपुट डेटा पर विचार करें:(ओपी प्लस दो अतिरिक्त पंक्तियों के नमूना डेटा के समान)

id  company_id  status_id   effective_date
-------------------------------------------
1   10          1           2016-12-15
2   10          1           2016-12-30 
3   10          5           2017-02-04
4   10          4           2017-02-08
5   11          5           2017-06-05
6   11          1           2018-04-30

आप निम्न क्वेरी का उपयोग कर सकते हैं:

SELECT t.id, t.company_id, t.status_id, t.effective_date, x.cnt
FROM company_status_history AS t
OUTER APPLY 
(
   SELECT COUNT(*) AS cnt
   FROM company_status_history AS c
   WHERE c.status_id = 1 
         AND c.company_id  = t.company_id 
         AND c.effective_date < t.effective_date
) AS x
ORDER BY company_id, effective_date

पाने के लिए:

id  company_id  status_id   effective_date  grp
-----------------------------------------------
1   10          1           2016-12-15      0
2   10          1           2016-12-30      1
3   10          5           2017-02-04      2
4   10          4           2017-02-08      2
5   11          5           2017-06-05      0
6   11          1           2018-04-30      0

अब आप status = 1 . की पहचान कर सकते हैं द्वीपों का उपयोग:

;WITH CTE AS 
(
    SELECT t.id, t.company_id, t.status_id, t.effective_date, x.cnt
    FROM company_status_history AS t
    OUTER APPLY 
    (
       SELECT COUNT(*) AS cnt
       FROM company_status_history AS c
       WHERE c.status_id = 1 
             AND c.company_id  = t.company_id 
             AND c.effective_date < t.effective_date
    ) AS x
)
SELECT id, company_id, status_id, effective_date,
       ROW_NUMBER() OVER (PARTITION BY company_id ORDER BY effective_date) - 
       cnt AS grp
FROM CTE 

आउटपुट:

id  company_id  status_id   effective_date  grp
-----------------------------------------------
1   10          1           2016-12-15      1
2   10          1           2016-12-30      1
3   10          5           2017-02-04      1
4   10          4           2017-02-08      2
5   11          5           2017-06-05      1
6   11          1           2018-04-30      2

परिकलित फ़ील्ड grp उन द्वीपों की पहचान करने में हमारी मदद करेगा:

;WITH CTE AS 
(
    SELECT t.id, t.company_id, t.status_id, t.effective_date, x.cnt
    FROM company_status_history AS t
    OUTER APPLY 
    (
       SELECT COUNT(*) AS cnt
       FROM company_status_history AS c
       WHERE c.status_id = 1 
             AND c.company_id  = t.company_id 
             AND c.effective_date < t.effective_date
    ) AS x
), CTE2 AS 
(
   SELECT id, company_id, status_id, effective_date,
          ROW_NUMBER() OVER (PARTITION BY company_id ORDER BY effective_date) - 
          cnt AS grp
   FROM CTE
)
SELECT company_id, 
       MIN(effective_date) AS start_date, 
       CASE 
          WHEN COUNT(*) > 1 THEN DATEADD(DAY, -1, MAX(effective_date))
          ELSE MIN(effective_date)
       END AS end_date
FROM CTE2 
GROUP BY company_id, grp
HAVING COUNT(CASE WHEN status_id = 1 THEN 1 END) > 0

आउटपुट:

company_id  start_date  end_date
-----------------------------------
10          2016-12-15  2017-02-03 
11          2018-04-30  2018-04-30 

आप केवल इतना जानना चाहते हैं कि ऊपर के वे रिकॉर्ड निर्दिष्ट अंतराल के साथ ओवरलैप करते हैं।

यहां डेमो करें कुछ अधिक जटिल उपयोग के मामले के साथ।



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. SQL 2005 sp_GetAppLock --- sp_ReleaseAppLock को कब कॉल करें?

  2. जावा से तालिका-मूल्यवान पैरामीटर के साथ संग्रहीत कार्यविधि को कॉल करें

  3. EF4 में NOLOCK संकेत का उपयोग करना?

  4. SQL सर्वर 2008 में चुनिंदा क्वेरी परिणाम से तालिका कैसे बनाएं?

  5. SQL:एक पंक्ति को अपडेट करें और 1 क्वेरी के साथ एक कॉलम मान लौटाएं