跳过行(发现基于开始日期结束日期和工作日)
鉴于这两个(简化)表:跳过行(发现基于开始日期结束日期和工作日)
Task (list of tasks/employee with their start date and estimated cost)
---------
TaskId: int
EmpId: int
Start: Date
Days: int
WorkableDays (list of working dates/employee - i.e., without weekends/holidays)
---------
EmpId: int
Day: Date
有什么办法只使用访问SQL得到这个结果(或任何对于这个问题的其他SQL)?
TaskId, EmpId, EndDate
编辑:如果它简化了事情的任何,这是每个任务的一个员工(taskid的是这里的唯一键,而不是任务id + EMPID)
(我包括EMPID为了完整起见,我不确定它是否与这个问题有关)
注意:我认为我在推动我的这个运气,但我试图弄清楚我是否可以在SQL中完成。
你可以有一个where
条款,说必须有开始和结束日期之间的N个工作日。与row_number()
变体不同,这应该在MS Access中起作用。例如:
declare @Task table (taskid int, empid int, start date, days int)
insert @Task values (1, 1, '2010-01-01', 1)
insert @Task values (2, 1, '2010-01-01', 2)
insert @Task values (3, 1, '2010-01-01', 3)
declare @WorkableDays table (empid int, day date)
insert @WorkableDays values (1, '2010-01-01')
insert @WorkableDays values (1, '2010-01-02')
insert @WorkableDays values (1, '2010-01-05')
select t.taskid
, t.start
, endday.day as end
from @Task t
join @WorkableDays endday
on endday.empid = t.empid
where t.days =
(
select COUNT(*)
from @WorkableDays wd
where wd.empId = t.empId
and wd.day between t.start and endday.day
)
此打印:
taskid start end
1 2010-01-01 2010-01-01
2 2010-01-01 2010-01-02
3 2010-01-01 2010-01-05
不知道有关访问,我很害怕,但在T-SQL,我会做这样的事情(员工1,任务1,在这个例子中):
SELECT
TaskId,
EmpId,
Day AS EndDate
FROM
(
SELECT
task.TaskId,
task.EmpId,
task.Days,
WorkableDays.Day,
RANK() OVER (PARTITION BY task.EmpID, task.TaskID ORDER BY Day ASC) 'TaskActualDayNumber'
FROM
task
INNER JOIN WorkableDays ON task.empID = WorkableDays.empID AND WorkableDays.Day >= task.Start
WHERE
task.EmpID = 1 AND
task.TaskID = 1
) CalculateDayNumbers
WHERE
Days = TaskActualDayNumber
内部查询将按照WorkableDays中可用天数的升序对未来任务的日期进行排序,因此在开始日期之后的所有未来日期中都会预测“此任务的日期”值。然后,外部查询只选择一个值,其中该日数与该任务估计的天数一致。
编辑:正如Michael Pakhantsov指出的,ROW_NUMBER()在这种情况下会产生与RANK()相同的结果,我认为。
谢谢!正如你所说,没有太多的Access吞咽的机会:)只是出于好奇,是在任务的前面#开始一个错字? – Benjol 2010-09-09 10:32:31
@Benjol哎呀!是的,这是一个错字 - 我使用临时表(用SQL Server上的#表示)测试了这个错误,并且在我编辑表名时回到原来的位置时错过了一个... – 2010-09-09 10:34:42
SELECT o.TaskId, o.EmpId, o.Date
FROM
(
SELECT TaskId, EmpId, t.Days, w.date, ROW_NUMBER() OVER(PARTITION BY w.EmpId order BY w.Date) DayNumber
FROM Task t, DayNumberWorkableDays w
WHERE t.EmpId = w.EmpId
AND w.Date >= t.Start
) o
WHERE o.DayNumber = o.Days
您应该可以在TaskID上进行分区 – Andomar 2010-09-09 10:33:46
非常好,有一个小小的更正(阅读编辑),这个答案的作品。非常感谢你! – Benjol 2010-09-09 12:21:46