代码之家  ›  专栏  ›  技术社区  ›  Benjol

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

sql
  •  2
  • Benjol  · 技术社区  · 14 年前

    给出这两个(简化的)表格:

    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
    

    是否有任何方法可以使用just Access SQL(或任何其他SQL)获得这个结果?

    TaskId, EmpId, EndDate
    

    :如果它简化了任何事情,那么每个任务只有一个雇员(TaskId是这里的唯一键,而不是TaskId+EmpId)

    (为了完整起见,我加入了EmpId,我不确定它是否与问题相关)

    注意:我想这是我的运气使然,但我正在努力弄清楚我是否能用SQL来实现它。

    3 回复  |  直到 14 年前
        1
  •  2
  •   Benjol    14 年前

    你可以喝一杯 where 规定从开始日到结束日之间必须有N个工作日的条款。不像 row_number()

    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
    
        2
  •  0
  •   Michael Pakhantsov    14 年前

         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
    
        3
  •  0
  •   Matt Gibson    14 年前

    恐怕我不知道Access,但在t-SQL中,我会这样做(在本例中,对于employee 1,task 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
    

    内部查询将按照工作日中可用天数的升序排列任务未来的天数,因此在从开始日期开始的所有未来日期中向前投影“此任务的日期”值。然后外部查询只选择一个值,其中该天数与任务的估计天数一致。