时间段的累加,高分考验你

sunshareforever 2003-09-04 04:15:07
表结构table1(开始日期,结束日期,费用名称,费用金额)

正常一条数据的'天数'是(结束日期-开始日期)

有什么办法可以算出所有数据的时间天数和????

因为要考虑的是时间有没有重复 ,还要去掉重复值,所以算法比较棘手
如下面的情况是有重复值的,
20010308,20010312,ss,100
20010309,20010315,aa,100
20010314,20010422,cc,200

我在线候,等大家好办法
...全文
56 24 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
24 条回复
切换为时间正序
请发表友善的回复…
发表回复
railgunman 2003-09-05
  • 打赏
  • 举报
回复
hao
cmain83 2003-09-05
  • 打赏
  • 举报
回复
geyobing(银翼天使)
的方法不错..
liyangyao970 2003-09-05
  • 打赏
  • 举报
回复
Dao~
Niuniu2003 2003-09-05
  • 打赏
  • 举报
回复
你取开始日期最小,结束日期最大
select Max(结束日期)-min(开始日期) as 总天数 from yourtable
大地精灵 2003-09-05
  • 打赏
  • 举报
回复
var
i:integer;
s_d:DateTime;//定义个变量记录上一条记录的结束时间
begin
query1.close;
query1.sql.clear;
query1.sql.add('select * from 你的表 order by 你的开始日期')
query1.open;
query1.first;
i:= i + 计算第一条记录的天数;
s_d := 第一条结束时间
query1.next;
while not query1.eof do
bgein
i := i + 该记录的天数;
if s_d > 该记录的开始时间
bgein
求出该减去的天数
i := i - 该减去的天数
end;
s_d := 该记录的结束时间
query.next;
end;

最后的I就是你要求出来的天数

昨天晚上太忙,可能写的不是太清楚,中间有点小的没写好,现在改了一下在上面,应该很容易理解的,在加上wdsimon(老王)的解说,我想楼主,应该没问题了吧
wdsimon 2003-09-04
  • 打赏
  • 举报
回复
楼上的思路是绝对正确的,

按开始日期升序排序,如下:
开始1,结束1,
开始2,结束2,
开始3,结束3,
开始4,结束4,
。。。。。
开始n-1,结束n-1,
开始n,结束n,

如果 结束n-1<开始n,
因为 开始n<开始n+1(升序排列),开始n<结束n
所以 结束n-1<所有以后记录,
又因 结束n-1 以后记录以 开始n最小,
所以其间若有间隔,开始n-结束n-1=间隔天数

那么只要做个循环,对 结束n-1<开始n 的情况取出间隔天数就OK了
大地精灵 2003-09-04
  • 打赏
  • 举报
回复
var
i:integer;
定义个变量记录上一条记录的结束时间 s_d
begin
query1.close;
query1.sql.clear;
query1.sql.add('select * from 你的表 order by 你的开始日期')
query1.open;
query1.first;
i:= i + 计算第一条记录的时间;
s_d := 结束时间
query1.next;
while not query1.eof do
bgein
i := i + 该记录的时间;
if s_d > 该记录的开始时间
bgein
求出该减去的天数
i := i + 该减去的天数
end;
s_d := 结束时间
query.next;
end;

这个是语句加描述,希望你能看的懂,因为这边没有DELPHI,就没有帮你写成代码,呵呵
zhoutian618 2003-09-04
  • 打赏
  • 举报
回复
问题没有描述清楚,
去掉重复值,
基于什么字段去重复值啊.
大地精灵 2003-09-04
  • 打赏
  • 举报
回复
我的想法,你是先按开始日期ORDER BY,然后循环调每条记录,判断后面一条记录的开始日期跟前面的结束日期相比较,那样不就能实现你所要得啦,代码我想你能自己搞定了吧
sunshareforever 2003-09-04
  • 打赏
  • 举报
回复
不错,看了大家的回复真的都很好,

小青的思路更是有灵感,不过也许我描述的不是很完整,有的回复会产生误差

因为还会出现一种情况就是:时间段是不可能都是连续的,可以断开,

虽然是按小青的思路很好,但实际编码我总是找不到感觉。

A_ZHU(诸葛祥云) 的办法,好像也会产生数据误差。。。

因为代码只控制了二条挨的数据的时间段,可能第三,四条的时间也在第一条的时间段内

谢谢大家

gzing

大家有什么好的办法请继续,分不够再加。。。
wmh_654321 2003-09-04
  • 打赏
  • 举报
回复
h2yang(小青)的方法应该可以,我这还有一个笨办法
先取出最小和最大的时间,然后得到这个时间段中所有的日期,用一个循环一个一个日期判断数据库中是否包含此日期,如果包含计数器加一,不包含则跳到下一个日期。
A_ZHU 2003-09-04
  • 打赏
  • 举报
回复
好像不对!

当一个完全包含在内就错了!
A_ZHU 2003-09-04
  • 打赏
  • 举报
回复
var
l_DateTime_Start,
l_DateTime_End: TDateTime;
l_Int_Days: Integer;
begin
with ADOQuery Do
//首先Odery By StartDate
l_Int_Days := 0;
for i := 0 to Recordcount-1 do
begin
l_DateTime_Start := FieldValues['StartDate'];
l_DataTime_End := FieldValues['EndDate'];
l_Int_Days := l_Int_Days + (l_DateTime_Start - l_DateTime_Start);
Next;
if FieldValues['StartDate'] < l_DataTime_End then
l_Int_Days := l_Int_Days - (l_DataTime_End - StartDate);
end;
end;
End;

把相应的字段内容替换,看要得不?

h2yang 2003-09-04
  • 打赏
  • 举报
回复
to h2yang(小青): 如果开始2,结束1之间有时间间隔咋办!

在我的思踟中,已经解决了这个问题了。
是我的

开始1,开始2,结束1,开始3,结束2,结束3。
这里要得出的值应该是结束3-开始1。

这个例子中,开始2,结束1之间的时间间隔可以不关心。
kexian 2003-09-04
  • 打赏
  • 举报
回复
用程序可以吗?
如果可以就用循环来做,就比较简单.
江山易改 2003-09-04
  • 打赏
  • 举报
回复
select Convert(int,max(结束日期)-min(开始日期)) as 天数 from ur table
where your condition
A_ZHU 2003-09-04
  • 打赏
  • 举报
回复
to h2yang(小青): 如果开始2,结束1之间有时间间隔咋办!
fansnaf 2003-09-04
  • 打赏
  • 举报
回复
同意 wdsimon(老王)

你取开始日期最小,结束日期最大
select datediff(day,min(开始日期),max(结束日期)) as 总天数 from yourtable
h2yang 2003-09-04
  • 打赏
  • 举报
回复
花和老王两个朋友的算法得出的结果会比实际结果大。
h2yang 2003-09-04
  • 打赏
  • 举报
回复
我有感觉了。
从数学角度上看好象可以把所有的时间按开始和结束标在数轴上,然后计算所有时间段的和。
这里有个排序问题。
如:
开始1,开始2,结束1,开始3,结束2,结束3。
这里要得出的值应该是结束3-开始1。
如开始1,开始2,结束1,结束2,开始3,结束3。
这里要得出的值应该是结束2-开始1,然后再加上结束3-开始3。

这是整个思路,具体的代码实现你自己做了。

加载更多回复(4)

5,931

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 开发及应用
社区管理员
  • VCL组件开发及应用社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧