0

我正在为我工​​作的公司开发一个考勤应用程序。每个员工都会有一个分配给他们的“工作时间表”。这个时间表可能多年来保持不变,也可能在一周内更改两次。所以我创建了一个如下表。该表允许应用程序了解每个员工在任何给定日期的有效时间表。该表的列是: 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 协议,所以我默认那些知道的人。

4

2 回答 2

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功能并获取每个用户的最新日期对应的行。

于 2015-10-21T13:03:55.420 回答
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
);
于 2015-10-21T13:05:47.167 回答