我正在为我工作的公司开发一个考勤申请表。每位员工都将拥有一份分配给他们的“工作时间表”。此计划可能在数年和数年内保持不变,或者可能在一周内更改两次。所以我创建了一个如下表格。该表允许应用程序知道每个员工在任何给定日期有效的计划。表的列是: 1.主键(带自动增量触发器) 2.时间表的ID 3.员工的ID 4.时间表生效日期
C_ID SCHEDULE_CID USER_CID EFFECTIVE_DATE
98 27 1188685432 15-OCT-15 00:00:00
100 25 1188685432 16-OCT-15 00:00:00
101 26 1188685432 18-OCT-15 00:00:00
102 27 1904229547 14-OCT-15 00:00:00
103 25 1904229547 19-OCT-15 00:00:00
因此,为了确定哪个时间表对任何给定日期的员工有效,我可以运行以下查询,这似乎返回了我想要的内容:
select Schedule_Cid, Effective_Date from Lei_Tas_People_Schedules
where Effective_Date = (select max(Effective_Date) from Lei_Tas_People_Schedules
where Lei_Tas_People_Schedules.User_Cid = '1188685432'
and Effective_Date <= '19-oct-2015');
在此示例中,将返回: 26 18-OCT-15 00:00:00
基于上面的例子,2015年10月19日,员工1188685432,ID 26的时间表生效。
问题是,我有时需要获得在给定日期对所有450名员工有效的计划。我的问题是:什么是最佳解决方案,将在给定日期返回所有员工的时间表(不运行上述查询450次 - 这似乎非常低效)?或者有更好的方法来设计我的数据结构来实现我想要的吗?
我考虑过存储过程,但似乎我需要一个光标,我听说应该避免使用它。无论如何我不是SQL大师,但我愿意学习。
非常感谢。
编辑:请原谅我,我可以看到我的上述选择查询存在缺陷。我的问题仍然是“如何在给定日期之前为所有450名员工返回有效的时间表?” 编辑:至于这可能是另一个问题的重复,我会说以下内容:我收到的这个问题的答案似乎与“可能重复”问题的答案不同。也许我的问题是一样的,但不会有其他答案值得保持这个问题吗?特别是因为他们似乎是正确的答案。我不知道SO协议,所以我默认那些知道的人。答案 0 :(得分:1)
select user_cid, Schedule_Cid, Effective_Date
from (
select user_cid, Schedule_Cid, Effective_Date,
row_number() over(partition by user_cid order by effective_date desc) as rn
from Lei_Tas_People_Schedules) t
where rn = 1
您可以使用row_number
函数,并为每个用户获取包含最新日期的相应行。
答案 1 :(得分:1)
您要做的是对您的记录进行排名,以便找到每个人的最佳记录(即最新记录)。您使用ROW_NUMBER执行此操作,为每个人记录编号,以便提供最新的#1。然后只保留那些。
select
user_cid,
schedule_cid,
effective_date
from
(
select
user_cid,
schedule_cid,
effective_date,
row_number() over (partition by user_cid
order by effective_date desc) as rn
from lei_tas_people_schedules
where effective_date <= date'2015-10-19'
)
where rn = 1;
顺便说一下,你可以用你自己的方法做同样的事情。只是,使用分析函数应该更好,因为你只读了一次表。
select *
from lei_tas_people_schedules
where (user_cid, effective_date) in
(
select user_cid, max(effective_date)
from lei_tas_people_schedules
where effective_date <= date'2015-10-19'
group by user_cid
);