ข้อความค้นหาปัจจุบันของคุณไม่ได้ให้ผลลัพธ์ตามที่ต้องการเนื่องจากคุณใช้ส่วน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 Fiddle พร้อมเดโม
หรือคุณสามารถใช้ฟังก์ชั่นหน้าต่างเพื่อส่งคืนแถวข้อมูลสำหรับแต่ละโรงเรียนด้วยข้อมูลล่าสุด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 Fiddle พร้อมเดโม
แบบสอบถามนี้การดำเนินการrow_number()
ซึ่งกำหนดจำนวนที่ไม่ซ้ำกันในแต่ละแถวในพาร์ติชันของและวางไว้ในลำดับถัดลงมาบนพื้นฐานของSCHOOL_CODE
LAST_UPDATE_DATE_TIME
ในฐานะที่เป็นข้อความด้านข้าง JOIN พร้อมฟังก์ชันการรวมไม่เหมือนกับrow_number()
เวอร์ชั่นทุกประการ หากคุณมีสองแถวที่มีเวลากิจกรรมเดียวกัน JOIN จะส่งคืนทั้งสองแถวในขณะที่row_number()
จะส่งคืนเพียงแถวเดียว หากคุณต้องการคืนค่าทั้งสองด้วยฟังก์ชั่น windowing ให้ลองใช้rank()
ฟังก์ชั่น windowing แทนเพราะมันจะคืนค่าความสัมพันธ์:
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;
ดูการสาธิต