2010-08-31 15 views
9

मेरे पास एक आईडी है जिसमें कई आईडी और प्रत्येक आईडी से जुड़े कई तिथियां हैं, और यहां तक ​​कि कुछ आईडी बिना किसी तारीख के हैं। प्रत्येक आईडी और दिनांक संयोजन के लिए, मैं आईडी, दिनांक और अगली सबसे बड़ी तारीख को उसी आईडी से भी जोड़ना चाहता हूं, या अगली तारीख के रूप में शून्य अगर कोई मौजूद नहीं है।एसक्यूएल - अगली तारीख क्वेरी का चयन करें

नमूना तालिका:

ID  Date 
1  5/1/10 
1  6/1/10 
1  7/1/10 
2  6/15/10 
3  8/15/10 
3  8/15/10 
4  4/1/10 
4  4/15/10 
4  

वांछित आउटपुट:

ID  Date  Next_Date 
1  5/1/10  6/1/10 
1  6/1/10  7/1/10 
1  7/1/10  
2  6/15/10  
3  8/15/10  
3  8/15/10  
4  4/1/10  4/15/10 
4  4/15/10  
+0

आपका डेटाबेस – Bharat

उत्तर

13
SELECT 
    mytable.id, 
    mytable.date, 
    (
     SELECT 
      MIN(mytablemin.date) 
     FROM mytable AS mytablemin 
     WHERE mytablemin.date > mytable.date 
      AND mytable.id = mytablemin.id 
    ) AS NextDate 
FROM mytable 

यह एसक्यूएल सर्वर 2008 R2 पर परीक्षण किया गया (लेकिन यह अन्य DBMSs पर काम करना चाहिए) और निम्न उत्पादन का उत्पादन:

 
id   date     NextDate 
----------- ----------------------- ----------------------- 
1   2010-05-01 00:00:00.000 2010-06-01 00:00:00.000 
1   2010-06-01 00:00:00.000 2010-06-15 00:00:00.000 
1   2010-07-01 00:00:00.000 2010-08-15 00:00:00.000 
2   2010-06-15 00:00:00.000 2010-07-01 00:00:00.000 
3   2010-08-15 00:00:00.000 NULL 
3   2010-08-15 00:00:00.000 NULL 
4   2010-04-01 00:00:00.000 2010-04-15 00:00:00.000 
4   2010-04-15 00:00:00.000 2010-05-01 00:00:00.000 
4   NULL     NULL 

अद्यतन 1: उन लोगों के लिए है कि रुचि रखते हैं, मैंने SQL सर्वर 2008 R2 में दो प्रकारों के प्रदर्शन की तुलना की है (एक MIN कुल योग का उपयोग करता है और दूसरा ORDER BY के साथ शीर्ष 1 का उपयोग करता है):

दिनांक कॉलम पर किसी इंडेक्स के बिना, MIN संस्करण की लागत 0.0187916 थी और शीर्ष/ORDER संस्करण के संस्करण 0.115073 की लागत थी, इसलिए MIN संस्करण "बेहतर" था।

दिनांक कॉलम पर एक सूचकांक के साथ, उन्होंने समान रूप से प्रदर्शन किया।

ध्यान दें कि यह बस इन 9 रिकॉर्ड के साथ परीक्षण किया गया था ताकि परिणाम हो सकता है (बहुत) नकली ...

अद्यतन 2: परिणाम 10,000 समान रूप से वितरित यादृच्छिक रिकॉर्ड के लिए पकड़। क्वेरी द्वारा टॉप/ऑर्डर 100,000 रिकॉर्ड चलाने के लिए बहुत लंबा समय लगता है, मुझे इसे रद्द करना और छोड़ देना था।

+0

से, समेकित कार्यों की तुलना में ऑर्डरिंग का बेहतर उपयोग करना बेहतर है। यह आपके पास एक बड़ी मेज है विशेष रूप से –

+0

@Andrii: मैं अन्य डीबी के लिए बात नहीं कर सकता लेकिन SQL सर्वर पर इसे कोई फर्क नहीं पड़ता। यदि कोई अनुक्रमणिका है तो यह जानना पर्याप्त है कि यह केवल पहली पंक्ति पढ़ सकता है; अगर कोई अनुक्रमणिका नहीं है तो उसे पूरी तालिका को किसी भी तरह से स्कैन करना होगा। वास्तव में, इसके द्वारा ऑर्डर के साथ धीमा हो सकता है क्योंकि इसे ओ (एन) एलएन (एन) स्कैन के बजाय ओ (एन * एलजी (एन)) सॉर्ट करना होगा। –

+0

यह एक mssql डीबी है जिसका उपयोग क्वेरी के माध्यम से पारित किया जा रहा है जिसका अर्थ है कि LIMIT क्वेरी वैसे भी काम नहीं करेगी। उपरोक्त न्यूनतम क्वेरी WHERE कथन में mytable.id = mytablemin.id जोड़ने के मामूली जोड़ के साथ पूरी तरह से काम करती है। क्वेरी थोड़ा सुस्त है, लेकिन अभी जिस तारीख क्षेत्र का उपयोग कर रहा हूं उस पर एक इंडेक्स नहीं है। सहायता के लिए सभी धन्यवाद। – John

1

SELECT id, date, (SELECT date FROM table t1 WHERE t1.date > t2.date ORDER BY t1.date LIMIT 1) FROM table t2

1

अपने डाटाबेस देववाणी है, तो आप lead() and lag() कार्यों का उपयोग कर सकते हैं।

SELECT id, date, 
LEAD(date, 1, 0) OVER (PARTITION BY ID ORDER BY Date DESC NULLS LAST) NEXT_DATE, 
FROM Your_table 
ORDER BY ID; 
+0

क्या उपरोक्त कोड मेरे लिए एक त्रुटि उत्पन्न करता है - 0 ओरेकल एसक्यूएल के रूप में शून्य होना चाहिए क्योंकि यह एक असंगत डेटा प्रकार (दिनांक की बजाय संख्या) के बारे में शिकायत करता है, हालांकि नीचे दिए गए काम ठीक है: चयन आईडी, दिनांक, लीड (दिनांक, 1, शून्य) ओवर (तिथि डीईएससी के अंतिम तिथि तक आईडी ऑर्डर द्वारा विभाजित) NEXT_DATE, आपके_टेबल – bawpie

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