背景:作者参与一个应用系统开发,其中移动端(外业人员)将定时上传最新位置,Web端(管理员)实时查看各个外业人员的最新位置。
数据:使用Oracle数据库,有一个表用于存储点位信息,字段结构如下:
F_LOCATIONID NUMBER not null,--位置序号
F_USERID NUMBER not null,--用户编号
F_TIME DATE not null,--获取位置的时间
F_LONGITUDE NUMBER(9,6) not null,--经度
F_LATITUDE NUMBER(8,6) not null,--纬度
F_ALTITUDE NUMBER(7,3),--海拔
F_AZIMUTH NUMBER(6,3),--方位角
F_SPEED NUMBER(6,3)--速度
功能:第一种是每个人当天的最后一个位置,作为当前位置;第二种是取每个人的最后10个点位,生成路线轨迹。
SQL要求:要能过按照人员进行分组(F_USERID),并且对每组中的位置按日期进行排序(F_TIME),判断每个日期是否为今天,取最后结果的前10条,或最大值。
SQL语句:第一种情况,每个人当天的最后一个位置:
select * from biz_locations a
inner join
(
select f_userid, max(f_time) f_time from biz_locations
group by f_userid
) b
on a.f_userid = b.f_userid and a.f_time = b.f_time
and to_number(sysdate - F_TIME)<1
说明:采用内连接方式,内表(b表)首先按用户分组,然后计算每个用户最后一个点位;然后外表(a表)再取其中属于当天的记录。
第二种情况:每个人当天的最后10个点位:
select * from
(
select f_userid,f_time,
row_number() over(partition by f_userid order by f_time desc) seq
from BIZ_LOCATIONS
where to_number(sysdate - F_TIME)<1
)
where seq<11
说明:首先看内表,选择了3个字段(f_userid, f_time, seq),其中seq字段是通过Oracle的分析函数得到的,表示根据用户分组并按时间排序,生成一个序号(序号是按分组排的,比如A用户有1、2、3序号,B用户也有1、2、3序号),内表完成了将当天所有记录按用户分组,按时间排序的操作,然后外表再选择每个用户的前10条记录。