2010-09-09 68 views
2

鉴于这两个(简化)表:跳过行(发现基于开始日期结束日期和工作日)

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中完成。

回答

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 
+0

非常好,有一个小小的更正(阅读编辑),这个答案的作品。非常感谢你! – Benjol 2010-09-09 12:21:46

0

不知道有关访问,我很害怕,但在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()相同的结果,我认为。

+0

谢谢!正如你所说,没有太多的Access吞咽的机会:)只是出于好奇,是在任务的前面#开始一个错字? – Benjol 2010-09-09 10:32:31

+0

@Benjol哎呀!是的,这是一个错字 - 我使用临时表(用SQL Server上的#表示)测试了这个错误,并且在我编辑表名时回到原来的位置时错过了一个... – 2010-09-09 10:34:42

0
在T-SQL

 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 
+0

您应该可以在TaskID上进行分区 – Andomar 2010-09-09 10:33:46

相关问题