Valitse päivämäärä tai viimeisin päivämäärä

Tässä on kaksi taulukkoa.

SCHOOL_STAFF

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

HENKILÖT

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

Tässä on minun Oracle-kyselyni.

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; 

mikä antaa tulokset

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

Haluan valita ensimmäisen koululle, jolla on viimeisin päivämäärä.

Kiitos.

vastaus

Nykyinen kyselysi ei anna toivottua tulosta, koska käytät GROUP BY -lauseke PERSON_ID -sarakkeessa, jolla on ainutlaatuinen arvo molemmille merkinnöille. Tämän seurauksena palaat molemmat rivit.

Voit ratkaista tämän muutamalla tavalla. Voit käyttää alakyselyä yhdistämistoiminnon palauttamiseksi max(LAST_UPDATE_DATE_TIME) kullekin 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; 

Katso SQL-esittely esittelyllä

Tai voit käyttää ikkunointitoiminto palauttaa kunkin koulun tietorivit viimeisimmällä 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; 

Katso SQL Fiddle with Demo

Tämä kysely toteuttaa row_number() , joka antaa yksilöllisen numeron kullekin riville SCHOOL_CODE -osiossa ja sijoitetaan laskevaan järjestykseen LAST_UPDATE_DATE_TIME.

Sivuhuomautuksena JOIN koostefunktiolla ei ole täsmälleen sama kuin row_number() -versio. Jos sinulla on kaksi riviä samalla tapahtuma-ajalla, JOIN palauttaa molemmat rivit, kun taas row_number() palauttaa vain yhden. Jos haluat palauttaa molemmat ikkunointitoiminnolla, harkitse sen sijaan rank() -toiminnon käyttöä, koska se palauttaa siteet:

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; 

Katso Demo

Kommentit

  • Kiitos, löydän sisempi liittäminen alakyselytaulukkoon (esimerkki 1 yllä) on intuitiivisin .. ja ei vaadi ' t vaadi minua oppimaan mikä osio on kaikki noin. Tässä on esimerkin 1 vastaava syntaksin kuvaus: valitse oT.dateField, oT.siteID, oT.field1, oT.field2, oT.field3 originalTable -kentästä oT sisäinen liitos (valitse max (dateField) uusimmaksiPäivämäärä, siteID alkuperäisestä taulukosta ryhmä siteID mukaan) uudeksi taulukoksi oT.siteID = newTable.site_ID ja oT.dateField = newTable.newestDate järjestyksessä oT.siteID asc ' tapahtuu alikyselyssä.

Vastaa

I ”Yllätyin siitä, että kukaan ei ole hyödyntänyt ikkunan toimintoja rivin_numero () ulkopuolella OVER () -lauseke luo ikkunan, jolle määrität aggregaattiryhmät. Tässä tapauksessa osioin vain SHOOL_CODE, joten näemme FIRST_VALUE, joka tulee LAST_UPDATE_DATE_TIME, ryhmitelty SCHOOL_CODE mukaan ja järjestyksessä LAST_UPDATE_DATE_TIME laskevassa järjestyksessä. Tätä arvoa käytetään koko sarakkeeseen jokaiselle SCHOOL_CODE-arvolle.

On tärkeää kiinnittää erityistä huomiota osiointiin ja tilaamiseen over () -lausekkeessa.

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 

Palauttaa:

24-JAN-13 ABE 111222 

Tämän pitäisi poistaa GROUP BY- ja Subqueries-kyselyt suurimmaksi osaksi. Muista kuitenkin sisällyttää DISTINCT.

Kommentit

  • Tämä on mukavaa, mutta onko tapa välttää toistamasta ylilauseketta kaikki sarakkeet?

Vastaa

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) 

Kommentit

  • Sen sijaan, että lähetät just -koodia, yritä selittää, miten tämä vastaa kysymykseen; ja mahdollisesti mitä toimenpideohjelma teki väärin.

Vastaa

Sähköpostiosoitettasi ei julkaista. Pakolliset kentät on merkitty *