return 450 行查询的最佳方式目前只有 return 一个
Best way to return 450 rows with query that currently only returns one
我正在为我工作的公司开发考勤应用程序。每个员工都会有一个分配给他们的 "work schedule"。这个时间表可能年复一年地保持不变,也可能在一周内改变两次。所以我创建了一个 table 如下所示。 table 允许应用程序了解每个员工在任何给定日期的有效时间表。 table 的列是:
1.主键(带自增触发器)
2. 日程ID
3.员工身份证
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
因此,要确定在任何给定日期哪个时间表对员工有效,我可以 运行 以下查询,这似乎 return 我想要的:
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');
在这个例子中,return:
26 15 年 10 月 18 日 00:00:00
所以根据上面的例子,2015年10月19日员工1188685432,ID为26的排班生效。
问题是,有时我需要获取在给定日期对所有 450 名员工有效的时间表。我的问题是:最好的解决方案是 return 所有员工在给定日期的日程安排(没有 运行 上述查询 450 次——这看起来效率很低)?或者有没有更好的方法来设计我的数据结构来完成我想要的?
我考虑过存储过程,但似乎我需要一个游标,我听说应该避免使用游标。无论如何,我都不是 SQL 大师,但我愿意学习。
非常感谢。
编辑:请原谅我,我可以看到我上面的 select 查询是有缺陷的。我的问题还是一样"How can I return the effective schedules for all 450 employees for a given date?"
编辑:至于这可能是另一个问题的重复,我会说以下内容:我收到的这个问题的答案似乎与 "possible duplicate" 问题的答案不同。也许我的问题是差不多的,但是其他答案不值得让这个问题保持开放吗?特别是因为它们似乎是正确的答案。不懂SO协议,所以默认给懂的人。
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
函数并为每个用户获取具有最新日期的相应行。
您要做的是对您的记录进行排名,以便为每个人找到最好的(即最新的)记录。您使用 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;
顺便说一句,你也可以用你自己的方法做同样的事情。只是,使用解析函数应该会更好,因为你只读了一次 table。
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
);
我正在为我工作的公司开发考勤应用程序。每个员工都会有一个分配给他们的 "work schedule"。这个时间表可能年复一年地保持不变,也可能在一周内改变两次。所以我创建了一个 table 如下所示。 table 允许应用程序了解每个员工在任何给定日期的有效时间表。 table 的列是: 1.主键(带自增触发器) 2. 日程ID 3.员工身份证 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
因此,要确定在任何给定日期哪个时间表对员工有效,我可以 运行 以下查询,这似乎 return 我想要的:
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');
在这个例子中,return: 26 15 年 10 月 18 日 00:00:00
所以根据上面的例子,2015年10月19日员工1188685432,ID为26的排班生效。
问题是,有时我需要获取在给定日期对所有 450 名员工有效的时间表。我的问题是:最好的解决方案是 return 所有员工在给定日期的日程安排(没有 运行 上述查询 450 次——这看起来效率很低)?或者有没有更好的方法来设计我的数据结构来完成我想要的?
我考虑过存储过程,但似乎我需要一个游标,我听说应该避免使用游标。无论如何,我都不是 SQL 大师,但我愿意学习。
非常感谢。
编辑:请原谅我,我可以看到我上面的 select 查询是有缺陷的。我的问题还是一样"How can I return the effective schedules for all 450 employees for a given date?"
编辑:至于这可能是另一个问题的重复,我会说以下内容:我收到的这个问题的答案似乎与 "possible duplicate" 问题的答案不同。也许我的问题是差不多的,但是其他答案不值得让这个问题保持开放吗?特别是因为它们似乎是正确的答案。不懂SO协议,所以默认给懂的人。
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
函数并为每个用户获取具有最新日期的相应行。
您要做的是对您的记录进行排名,以便为每个人找到最好的(即最新的)记录。您使用 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;
顺便说一句,你也可以用你自己的方法做同样的事情。只是,使用解析函数应该会更好,因为你只读了一次 table。
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
);