这里有两张表。
学校员工
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
这是我的 Oracle 查询。
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
我想为日期最晚的学校选择第一个。
谢谢。
您当前的查询没有给出期望的结果,因为您
GROUP BY
在列上使用了一个子句,该子句对PERSON_ID
两个条目都具有唯一值。结果,您将返回两行。有几种方法可以解决这个问题。您可以使用子查询来应用聚合函数以返回
max(LAST_UPDATE_DATE_TIME)
for eachSCHOOL_CODE
:请参阅带有演示的 SQL Fiddle
或者,您可以使用窗口函数返回每所学校最新的数据行
LAST_UPDATE_DATE_TIME
:请参阅带有演示的 SQL Fiddle
此查询实现
row_number()
为分区中的每一行分配一个唯一编号,SCHOOL_CODE
并根据LAST_UPDATE_DATE_TIME
.附带说明一下,带有聚合函数的 JOIN 与版本不完全相同
row_number()
。如果您有两行具有相同的事件时间,则 JOIN 将返回两行,而row_number()
将只返回一个。如果您想使用窗口函数返回两者,请考虑使用rank()
窗口函数,因为它将返回关系:看演示
我很惊讶没有人利用 row_number() 之外的窗口函数
这里有一些数据可以玩:
OVER() 子句创建一个窗口,您将为其定义聚合组。在这种情况下,我只对 SHOOL_CODE 进行分区,因此我们将看到 FIRST_VALUE,它来自 LAST_UPDATE_DATE_TIME,按 SCHOOL_CODE 分组,并按 LAST_UPDATE_DATE_TIME 降序排列。该值将应用于每个 SCHOOL_CODE 的整个列。
密切注意 over() 子句中的分区和排序非常重要。
回报:
这应该在很大程度上消除了您对 GROUP BY 和子查询的需求。不过,您需要确保包含 DISTINCT。