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.