चुनें जिसमें अधिकतम तिथि या नवीनतम तिथि है


15

यहाँ दो टेबल हैं।

स्कूल के कर्मचारी

SCHOOL_CODE + STAFF_TYPE_NAME + LAST_UPDATE_DATE_TIME + PERSON_ID
=================================================================
ABE           Principal         24-JAN-13               111222
ABE           Principal         09-FEB-12               222111

व्यक्तियों

PERSON_ID + NAME
=================
111222      ABC
222111      XYZ

यहाँ मेरी ओरेकल क्वेरी है।

SELECT MAX(LAST_UPDATE_DATE_TIME) AS LAST_UPDATE, SCHOOL_CODE, PERSON_ID
FROM SCHOOL_STAFF
WHERE STAFF_TYPE_NAME='Principal'
GROUP BY SCHOOL_CODE, PERSON_ID
ORDER BY SCHOOL_CODE;

जो यह परिणाम देता है

LAST_UPDATE SCHOOL_CODE PERSON_ID
===========+===========+=========
24-JAN-13   ABE         111222
09-FEB-12   ABE         222111

मैं उस स्कूल के लिए पहला चयन करना चाहता हूं जिसकी नवीनतम तिथि है।

धन्यवाद।

जवाबों:


28

आपकी वर्तमान क्वेरी वांछित परिणाम नहीं दे रही है क्योंकि आप स्तंभ GROUP BYपर एक खंड का उपयोग कर रहे हैं PERSON_IDजिसमें दोनों प्रविष्टियों के लिए एक अद्वितीय मूल्य है। परिणामस्वरूप आप दोनों पंक्तियों को वापस कर देंगे।

कुछ तरीके हैं जिनसे आप इसे हल कर सकते हैं। आप max(LAST_UPDATE_DATE_TIME)प्रत्येक के लिए वापस जाने के लिए कुल फ़ंक्शन को लागू करने के लिए एक सबक्वेरी का उपयोग कर सकते हैं SCHOOL_CODE:

select s1.LAST_UPDATE_DATE_TIME,
  s1.SCHOOL_CODE,
  s1.PERSON_ID
from SCHOOL_STAFF s1
inner join
(
  select max(LAST_UPDATE_DATE_TIME) LAST_UPDATE_DATE_TIME,
    SCHOOL_CODE
  from SCHOOL_STAFF
  group by SCHOOL_CODE
) s2
  on s1.SCHOOL_CODE = s2.SCHOOL_CODE
  and s1.LAST_UPDATE_DATE_TIME = s2.LAST_UPDATE_DATE_TIME;

SQL फिडेल को डेमो के साथ देखें

या आप सबसे हाल के साथ प्रत्येक स्कूल के लिए डेटा की पंक्तियों को वापस करने के लिए एक विंडो फ़ंक्शन का उपयोग कर सकते हैं LAST_UPDATE_DATE_TIME:

select SCHOOL_CODE, PERSON_ID, LAST_UPDATE_DATE_TIME
from
(
  select SCHOOL_CODE, PERSON_ID, LAST_UPDATE_DATE_TIME,
    row_number() over(partition by SCHOOL_CODE 
                        order by LAST_UPDATE_DATE_TIME desc) seq
  from SCHOOL_STAFF
  where STAFF_TYPE_NAME='Principal'
) d
where seq = 1;

SQL फिडेल को डेमो के साथ देखें

यह क्वेरी लागू होती है row_number()जो विभाजन के प्रत्येक पंक्ति में एक अद्वितीय संख्या निर्दिष्ट करती है SCHOOL_CODEऔर उसके आधार पर अवरोही क्रम में रखी जाती है LAST_UPDATE_DATE_TIME

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

select SCHOOL_CODE, PERSON_ID, LAST_UPDATE_DATE_TIME
from
(
  select SCHOOL_CODE, PERSON_ID, LAST_UPDATE_DATE_TIME,
    rank() over(partition by SCHOOL_CODE 
                        order by LAST_UPDATE_DATE_TIME desc) seq
  from SCHOOL_STAFF
  where STAFF_TYPE_NAME='Principal'
) d
where seq = 1;

डेमो देखें


4

मुझे आश्चर्य है कि किसी ने भी row_number () से परे विंडो फ़ंक्शंस का लाभ नहीं उठाया है

यहाँ कुछ डेटा के साथ खेलने के लिए है:

CREATE TABLE SCHOOL_STAFF
(
LAST_UPDATE_DATE_TIME VARCHAR(20),
SCHOOL_CODE VARCHAR(20),
PERSON_ID VARCHAR(20),
STAFF_TYPE_NAME VARCHAR(20)
);
INSERT INTO SCHOOL_STAFF VALUES ('24-JAN-13', 'ABE', '111222', 'Principal');
INSERT INTO SCHOOL_STAFF VALUES ('09-FEB-12', 'ABE', '222111', 'Principal');

OVER () क्लॉज एक विंडो बनाता है जिसके लिए आप अपने एग्रीगेट समूहों को परिभाषित करेंगे। इस मामले में, मैं केवल SHOOL_CODE पर विभाजन कर रहा हूं, इसलिए हम FIRST_VALUE देखेंगे, जो LAST_UPDATE_DATE_TIME से आएगा, SCHOOL_CODE द्वारा समूहीकृत और LAST_UPDATE_DATE_TIME के ​​क्रम में अवरोही क्रम से। यह मान प्रत्येक SCHOOL_CODE के लिए पूरे कॉलम पर लागू किया जाएगा।

ओवर () क्लॉज में अपने विभाजन और ऑर्डर पर पूरा ध्यान देना महत्वपूर्ण है।

SELECT DISTINCT
 FIRST_VALUE(LAST_UPDATE_DATE_TIME) OVER (PARTITION BY SCHOOL_CODE ORDER BY LAST_UPDATE_DATE_TIME DESC) AS LAST_UPDATE
,FIRST_VALUE(SCHOOL_CODE)           OVER (PARTITION BY SCHOOL_CODE ORDER BY LAST_UPDATE_DATE_TIME DESC) AS SCHOOL_CODE
,FIRST_VALUE(PERSON_ID)             OVER (PARTITION BY SCHOOL_CODE ORDER BY LAST_UPDATE_DATE_TIME DESC) AS PERSON_ID
FROM SCHOOL_STAFF
WHERE STAFF_TYPE_NAME = 'Principal'
ORDER BY SCHOOL_CODE

यह दिखाता है:

24-JAN-13   ABE 111222

यह अधिकांश भाग के लिए ग्रुप बीवाई और सबक्वेरीज के लिए आपकी आवश्यकता को समाप्त कर देना चाहिए। यद्यपि आप DISTINCT को शामिल करना सुनिश्चित करना चाहेंगे।


1
select LAST_UPDATE_DATE_TIME as LAST_UPDATE,
  SCHOOL_CODE,
  PERSON_ID
from SCHOOL_STAFF
WHERE STAFF_TYPE_NAME='Principal'
AND LAST_UPDATE_DATE_TIME = (SELECT MAX(LAST_UPDATE_DATE_TIME)
                            FROM SCHOOL_STAFF s2
                            WHERE PERSON_ID = s2.PERSON_ID)

1
सिर्फ कोड पोस्ट करने के बजाय , आपको यह समझाने का प्रयास करना चाहिए कि यह प्रश्न का उत्तर कैसे देता है; और संभवतः ओपी गलत तरीके से क्या कर रहा था।
मैक्स वेरनॉन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.