मान लीजिए मेरे पास इस तरह की एक टेबल है:

| id |       date | name | value |
|----|------------|------|-------|
|  0 | 2017-01-14 |  foo |   one |
|  1 | 2017-01-17 |  bar |   two |
|  2 | 2017-01-18 | john |  five |
|  3 | 2017-01-19 |  doe |   ten |

(जहां date को ऑर्डर करने की आवश्यकता नहीं है)

मैं पिछली पंक्ति (date पर आधारित) के कुछ मानों का चयन करने में सक्षम होना चाहता हूं। ऐसी कार्यक्षमता निम्न क्वेरी द्वारा प्राप्त की जा सकती है:

SELECT 
  *, 
  (SELECT 
     name 
   FROM 
     example e2 
   WHERE 
     e2.dt < e1.dt 
   ORDER BY dt DESC 
   LIMIT 1
   ) as prev_name 
FROM example e1

परिणामी तालिका के साथ:

| id |         dt | name | value | prev_name |
|----|------------|------|-------|-----------|
|  0 | 2017-01-14 |  foo |   one |    (null) |
|  1 | 2017-01-17 |  bar |   two |       foo |
|  2 | 2017-01-18 | john |  five |       bar |
|  3 | 2017-01-19 |  doe |   ten |      john |

अब, यह ठीक काम करता है। हालांकि, यह बेहतर होगा यदि मैं पिछली पंक्ति से आसानी से एकाधिक कॉलम चुन सकता हूं, जिसके परिणामस्वरूप परिणाम होगा:

| id |         dt | name | value | prev_name | prev_value |    prev_dt |
|----|------------|------|-------|-----------|------------|------------|
|  0 | 2017-01-14 |  foo |   one |    (null) |     (null) |     (null) |
|  1 | 2017-01-17 |  bar |   two |       foo |        one | 2017-01-14 |
|  2 | 2017-01-18 | john |  five |       bar |        two | 2017-01-17 |
|  3 | 2017-01-19 |  doe |   ten |      john |       five | 2017-01-18 |

यह निश्चित रूप से सबक्वेरी (SELECT [..] FROM example e2 ...) को कई बार क्वेरी में कॉपी करके पूरा किया जा सकता है, लेकिन मुझे लगता है कि यह जाने का बेहतर तरीका नहीं है। मुझे SO पर या तो "पिछली पंक्ति से रिकॉर्ड कैसे चुनें" या "सबक्वायरीज़ का उपयोग करके एकाधिक कॉलम कैसे चुनें" समस्या पर कई प्रश्न मिले हैं, लेकिन दोनों नहीं . बाद की समस्या को ज्यादातर JOIN कथन का उपयोग करके हल किया जाता है, लेकिन मुझे लगता है कि यह "पिछली पंक्ति" मामले के साथ संयोजन योग्य नहीं है। तो मेरा सवाल यह है: अंतिम परिणाम उत्पन्न करने का एक बेहतर तरीका क्या होगा, इसके बजाय हमें हर कॉलम के लिए एक सबक्वायरी की प्रतिलिपि बनाना चाहिए?

संपादित करें। एक अतिरिक्त बाधा के रूप में, जिसे मैंने मूल प्रश्न में शामिल नहीं किया था, "पिछला" वास्तव में पिछली पंक्ति से कुछ अलग हो सकता है, बल्कि "पिछली पंक्ति जो एक शर्त को पूरा करती है"। तो मान लीजिए कि मेरी तालिका में एक अतिरिक्त boolean कॉलम b है

| id |         dt | name | value | b |
|----|------------|------|-------|---|
|  0 | 2017-01-14 |  foo |   one | 1 |
|  1 | 2017-01-17 |  bar |   two | 0 |
|  2 | 2017-01-18 | john |  five | 1 |
|  3 | 2017-01-19 |  doe |   ten | 0 |

मैं चाहता हूं कि "पिछली पंक्ति" b = 1 के साथ पिछली पंक्ति हो, इसलिए वांछित परिणाम होगा:

| id |         dt | name | value | b | prev_name | prev_value |    prev_dt |
|----|------------|------|-------|---|-----------|------------|------------|
|  0 | 2017-01-14 |  foo |   one | 1 |    (null) |     (null) |     (null) |
|  1 | 2017-01-17 |  bar |   two | 0 |       foo |        one | 2017-01-14 |
|  2 | 2017-01-18 | john |  five | 1 |       foo |        one | 2017-01-14 |
|  3 | 2017-01-19 |  doe |   ten | 0 |      john |       five | 2017-01-18 |

मुझे लगता है कि यह अभी भी जेम्स स्कॉट के उत्तर द्वारा पूरा किया जा सकता है, केवल b = 1, IF -स्टेटमेंट का उपयोग करके केवल चर को अपडेट करके, लेकिन शायद इस मामले में एक और समाधान संभव है।

संपादित करें। SQLfiddle

1
konewka 25 अगस्त 2017, 14:43

2 जवाब

सबसे बढ़िया उत्तर

कुछ इस तरह 'पिछली' पंक्ति की आईडी लौटाएगा।

 SELECT x.*
      , MAX(y.id) prev_id
   FROM example x
   LEFT
   JOIN example y
     ON y.id < x.id 
    AND y.b = 1
  GROUP
     BY x.id;

मैं पाठक के लिए एक अभ्यास के रूप में इस पंक्ति से जुड़े शेष डेटा को वापस करने का व्यवसाय छोड़ दूँगा।

2
Strawberry 25 अगस्त 2017, 16:14

सत्र चर के लिए एक अच्छा उपयोग मामला लगता है यदि आप केवल पिछली पंक्ति चाहते हैं, तो आप अलग-अलग परिणाम प्राप्त करने के लिए ORDER BY का उपयोग कर सकते हैं।

SET @VDt := NULL, @VName := NULL, @VValue := NULL;

SELECT  id, @VName prev_name, @VValue prev_value, @VDt prev_dt, @VDt := dt dt, @VName := `name` `name`, @VValue := `value` `value` FROM example;

जब मैंने पहली बार पोस्ट किया तो इसे गड़बड़ कर दिया, ध्यान दें कि पिछली पंक्ति से वापस आने के बाद चर सेट किए जाने चाहिए। कॉलम को फिर से व्यवस्थित करने के लिए (यदि वांछित हो) आप इस क्वेरी को दूसरे में लपेट सकते हैं जो फिर परिणाम कॉलम को पुन: व्यवस्थित करता है।

आपको किसी और चीज़ की ज़रुरत हो तो मुझे बताएं,

सादर,

जेम्स

1
James Scott 25 अगस्त 2017, 14:53