MS Access复杂分组和总和

时间:2013-06-12 14:26:52

标签: sql ms-access

我有一个困难的访问问题,我似乎被困在了。我的数据如下表所示,每个人都有一个开始和结束日期以及两者之间的天数。我想要做的是将所有连续的分配长度加在一起,这意味着一个的结束日期是下一个的开始日期的前一天。在下面的例子中,我想总结记录1,2,3的分配长度和单独的总和4,5,因为在结束日期和开始日期之间有一个中断。它可以访问,所以我可以通过查询或使用vba进行访问,我不确定这里的最佳解决方案是什么。
ID名称StartDate EndDate AssignmentLength
1 - bob - 1/1/2013 - 2/1/2013 - 30
2 - bob - 2/2/2013 - 3/1/2013 - 30
3 - bob - 3/2/2013 - 4/1/2013 - 30
4 - bob - 5/1/2013 - 6/1/2013 - 30
5 - bob - 6/2/2013 - 7/1/2013 - 30

3 个答案:

答案 0 :(得分:2)

我在给定数据中添加了一条额外的记录:

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

有一个期间没有跨越记录。我将表命名为workperiods。

通过修改后的数据,我们可以找到工作期间开始于:

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

这可能是期望的结果。

它不漂亮,但我认为它到了那里。

答案 1 :(得分:1)

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

答案 2 :(得分: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