在sql查询中跳过行(根据开始日期和工作日查找结束日期)

时间:2010-09-09 10:11:42

标签: sql

鉴于这两个(简化)表格:

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中做到这一点,我正在努力解决。

3 个答案:

答案 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)

在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