鉴于这两个(简化)表格:
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
有没有办法只使用Access SQL(或任何其他SQL)获得此结果?
TaskId, EmpId, EndDate
编辑:如果它简化了任何事情,那么每个任务就是一名员工(TaskId是这里的唯一键,而不是TaskId + EmpId)
(为了完整起见,我包括EmpId,我不确定这个问题是否相关)
注意:我认为我正在推动这个运气,但是如果我能在SQL中做到这一点,我正在努力解决。
答案 0 :(得分:2)
你可以有一个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
答案 1 :(得分:0)
我不知道Access,我担心,但在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()相同的结果。答案 2 :(得分:0)
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