Válassza ki, hogy melyik dátum vagy a legutolsó dátum

Íme két táblázat.

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 

SZEMÉLYEK

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

Itt van az orákulum lekérdezésem.

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; 

ami ezt eredményezi

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

Szeretném kiválasztani az elsőt annak az iskolának, amelynek a legutóbbi dátuma van.

Köszönöm.

Válasz

Az aktuális lekérdezés nem adja meg a kívánt eredményt, mert egy GROUP BY záradék a PERSON_ID oszlopban, amelynek mindkét bejegyzéshez egyedi értéke van. Ennek eredményeként mindkét sort visszaadja.

Néhány módon megoldhatja ezt. Allekérdezéssel alkalmazhatja az összesítő függvényt a max(LAST_UPDATE_DATE_TIME) visszaadásához minden SCHOOL_CODE esetén:

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; 

Lásd: SQL Fiddle demóval

Vagy használhat egy ablakfüggvény a legfrissebb LAST_UPDATE_DATE_TIME összes iskola adatsorainak visszaadásához:

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; 

Lásd: SQL Fiddle with Demo

Ez a lekérdezés megvalósítja a row_number() , amely egyedi számot rendel a SCHOOL_CODE partíció minden sorához, és a LAST_UPDATE_DATE_TIME.

Megjegyzendő, hogy az összesített függvényű JOIN nem pontosan ugyanaz, mint a row_number() verzió. Ha két sorod van azonos eseményidővel, akkor a JOIN visszaadja mindkét sort, míg a row_number() csak egyet. Ha mindkettőt vissza szeretné adni egy ablakfüggvénnyel, akkor fontolja meg a rank() ablakfunkció használatát, mivel az viszonyt ad vissza:

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; 

Lásd: Demo

Megjegyzések

  • Köszönöm, megtalálom az allekérdező tábla belső illesztése (a fenti 1. példa), hogy a leg intuitívabb legyen .. és nem szükséges, hogy ' megköveteljem, hogy megtanuljam, mi az a partíció a ról ről. Íme egy pillantás az 1. példához hasonló szintaxisra: válassza az oT.dateField, oT.siteID, oT.field1, oT.field2, oT.field3 elemet az originalTable értékéből oT belső csatlakozás (válasszuk a max (dateField) -et legfrissebbDate-ként, siteID-t az originalTable-csoportból siteID szerint) newTable -ként az oT.siteID = newTable.site_ID és oT.dateField = newTable.newestDate sorrendben, amelyet oT.siteID asc talál nekem. Ez jobban megmagyarázza, mi ' s az allekérdezésben történik.

Válasz

I “Meglepődtem, hogy senki sem használta ki a sorszámon () túlmutató ablakfunkciók előnyeit.

Íme néhány adat, amellyel játszani lehet:

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"); 

Az OVER () záradék egy ablakot hoz létre, amelyhez megadja az összesített csoportokat. Ebben az esetben csak a SHOOL_CODE partíción vagyok, így látni fogjuk a FIRST_VALUE értéket, amely LAST_UPDATE_DATE_TIME-től fog származni, SCHOOL_CODE szerint csoportosítva és LAST_UPDATE_DATE_TIME sorrendben csökkenő sorrendben. Ez az érték minden SCHOOL_CODE oszlopra vonatkozik.

Fontos, hogy fokozott figyelmet fordítson a particionálásra és az over () záradékban történő megrendelésre.

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 

Visszaad:

24-JAN-13 ABE 111222 

Ezzel feleslegessé válik a GROUP BY és az Subqueries igénye javarészt. Mindenképpen ügyeljen arra, hogy a DISTINCT szerepeljen.

Megjegyzések

  • Ez nagyon jó, de van-e mód arra, hogy ne ismételjük a minden oszlop?

Válasz

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) 

Megjegyzések

  • A just kód feltöltése helyett meg kell próbálnia elmagyarázni, hogy ez hogyan válaszolja meg a kérdést; és potenciálisan azt, amit az OP helytelenül csinált.

Vélemény, hozzászólás?

Az email címet nem tesszük közzé. A kötelező mezőket * karakterrel jelöltük