我有一个难以访问的问题,我似乎被困住了。我的数据如下表所示,每个人都有一个开始和结束日期以及两者之间的天数。我要做的是将所有连续的作业长度加在一起,这意味着一个的结束日期是下一个开始日期的前一天。在下面的示例中,我想对记录 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 -- 鲍勃 -- 2013 年 3 月 2 日 -- 2013 年 4 月 1 日 -- 30
4 -- 鲍勃 -- 2013 年 5 月 1 日 -- 2013 年 6 月 1 日 -- 30
5 -- 鲍勃 -- 6/ 2013 年 2 月 -- 2013 年 7 月 1 日 -- 30
问问题
250 次
3 回答
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
这可能是想要的结果。
它不漂亮,但我认为它到达那里。
于 2013-06-12T16:35:47.673 回答
1
我会使用 VBA 和DateDiff()。然后您可以遍历每个并比较以查看总数是否小于 1。
于 2013-06-12T15:04:06.390 回答
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
于 2013-06-12T15:41:46.487 回答