2013-06-12 52 views
3

我有一个难以访问的问题,我似乎被卡住了。我的数据如下表所示,每个人都有一个开始和结束日期以及两者之间的天数。我试图做的是将所有连续的作业长度加在一起,这意味着一个的结束日期是下一个作业开始日期的前一天。在我下面的例子中,我想总结记录1,2,3的分配长度,并分别总结4,5,因为在结束日期和开始日期之间有一个中断。它的访问,所以我可以做一个查询或使用vba,我不知道这里最好的解决方案是什么。
ID名称的StartDate结束日期AssignmentLength
1 - 鲍勃 - 2013年1月1日 - 2013年2月1日 - 30
2 - 鲍勃 - 2013年2月2日 - 3/1/2013 - 30
3 - bob - 3/2/2013 - 2013/1/1 - 30
4 - bob - 2013年5月1日 - 2013年6月1日 - 30
5 - 鲍勃 - 2013年6月2日 - 2013年7月1日 - 30
MS Access复合分组和总和

回答

2

我增加了一个额外的记录给定的数据:

periodID fname startdate enddate 
6   bob  8/1/2013 9/1/2013 

有一个时期,没有跨越记录。我给表格命名。

与修改后的数据,我们可以找到的工作周期开始:

SELECT * 
FROM workperiods 
WHERE periodid NOT IN 
    (SELECT a.periodid 
    FROM workperiods a 
    INNER JOIN workperiods b ON a.startdate =b.enddate+1); 

我们能找到的工作期间与

SELECT * 
FROM workperiods 
WHERE periodid NOT IN 
    (SELECT a.periodid 
    FROM workperiods a 
    INNER JOIN workperiods b ON a.enddate =b.startdate-1); 

结束之后,我们可以建立这个畸形:

SELECT startdate, 
     enddate, 
     enddate-startdate AS periodlength 
FROM 
    (SELECT startdate, 
      min(enddate) AS enddate 
    FROM 
    (SELECT c.startdate, 
      f.enddate 
     FROM 
     (SELECT * 
     FROM workperiods 
     WHERE periodid NOT IN 
      (SELECT a.periodid 
       FROM workperiods a 
       INNER JOIN workperiods b ON a.startdate =b.enddate+1)) AS c, 

     (SELECT * 
     FROM workperiods 
     WHERE periodid NOT IN 
      (SELECT d.periodid 
       FROM workperiods d 
       INNER JOIN workperiods e ON d.enddate =e.startdate-1)) AS f 
     WHERE f.startdate >c.enddate 
     OR c.startdate=f.startdate) 
    GROUP BY startdate) 

哪给出:

startdate enddate  periodlength 
1/1/2013 4/1/2013 90 
5/1/2013 7/1/2013 61 
8/1/2013 9/1/2013 31 

这可能是期望的结果。

这不是很漂亮,但我认为它到达那里。

+0

+1通过练习SQL解决方案。有时他们看起来有点可怕,但作为一个谜题,他们比启动VBA和循环记录集更有趣。 ;) –

+0

最终的结果正是我所期待的,希望它能起作用,我会让你知道的。 – user2478657

+0

@GordThompson谢谢你的客气话。它看起来像是可以用直接SQL来完成的,所以我想试试它。 – mikeY

1

我会用VBA和DateDiff()。然后你可以遍历每一个,并比较,看看总数是否小于1.

1

也许你可以从中得到一些想法。 AssignmentLength可以根据当月的实际长度进行修改。如果你有一些想法,请标记为已回答。

Sub dates() 
Dim cn As ADODB.Connection 
Dim rs As ADODB.Recordset 
Dim ConnStr As String 
''Dim below arrays 
Set cn = New ADODB.Connection 
ConnStr = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & _ 
    "C:\Users\Philosophaie\Documents\a access\a Chase.mdb;" 
cn.Open ConnStr 
Set rs = New ADODB.Recordset 
rs.Open Source:="Checking", ActiveConnection:=cn, _ 
    CursorType:=adOpenKeyset, LockType:=adLockOptimistic, _ 
    Options:=adCmdTableDirect 
rs.MoveFirst 
Do Until rs.EOF 
    If rs!Name = "bob" Then 
     n=n+1 
     datestart(n)=rs!StartDate 
     dateend(n)=rs!EndDate 
     assignmentlength(n)=rs!AssignmentLength 
    End If 
    rs.MoveNext 
Loop 
for i=1 to n 
    mostart(i)=Left(datestart(i),1) 
    dystart(i)=right(left(datestart,3),1) 
    yrstart(i)=right(datestart,4) 
''do the same for end 
next I 
for i=1 to n 
    if moend(I)=mostart(i) then 
     if dyend(I)=daystart(I)+1 then 
      if yrend(I)=yrstart(I) then 
       aslen(j)=assignmentlength(I)+aslen(j) 
      else 
       j=j+1 
      end if 
     else 
       j=j+1 
     end if 
    else 
     j=j+1 
    end if 
    next I 
''output 
End sub