取时间总数的问题,时间可能重复不连续

wuxiaoqqqq 2009-06-26 03:27:22
加精
有N条记录,每条都有一个StartDate和一个EndDate
求这些记录的Days的和.
要求去掉重复的时间,时间可能不连续

比如
1 2009-4-1 2009-5-1
2 2009-4-1 2009-5-1
3 2009-3-14 2009-4-12
4 2009-6-1 2009-6-30
这样的记录
...全文
128 26 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
26 条回复
切换为时间正序
请发表友善的回复…
发表回复
jxncszdfdh 2009-06-27
  • 打赏
  • 举报
回复
呵,挺繁雜的
qizhicong2 2009-06-27
  • 打赏
  • 举报
回复
是enddate-startdate
xl376 2009-06-27
  • 打赏
  • 举报
回复
学习中!!!!!!
--小F-- 2009-06-26
  • 打赏
  • 举报
回复
[Quote=引用 20 楼 libin_ftsafe 的回复:]
引用 17 楼 feixianxxx 的回复:
ID 1 和2 隔的天数 还有3 和4隔的天数 都是相互相同 不是只取 ID 为1 3 或者 2 4么?



根据分析楼主所提供的测试数据,第3条记录与第1、2两条重复的记录数据,在日期范围内存在一个交集,即 2009-04-01 --> 2009-04-12 ;故尔这三条记录可以被合并成一个大的时间区间,即 2009-03-14 --> 2009-05-01;这类问题归集为合并多个存在交集的时间区间或数字区间的问题。
[/Quote]

还是钻钻强悍
wuxiaoqqqq 2009-06-26
  • 打赏
  • 举报
回复
怎么变成推荐贴了,我还想来结帖的。。。
ljking0731 2009-06-26
  • 打赏
  • 举报
回复
create table #temp(autoid int identity(1,1),startDate datetime, endDate datetime)

insert into #temp
select '2009-4-1','2009-5-1' union all
select '2009-4-1','2009-5-1' union all
select '2009-3-14','2009-4-12' union all
select '2009-6-1','2009-6-30'

autoid startDate endDate
----------- ----------------------- -----------------------
1 2009-04-01 00:00:00.000 2009-05-01 00:00:00.000
2 2009-04-01 00:00:00.000 2009-05-01 00:00:00.000
3 2009-03-14 00:00:00.000 2009-04-12 00:00:00.000
4 2009-06-01 00:00:00.000 2009-06-30 00:00:00.000

(4 行受影响)

----------
select sum(counts) from
(
select datediff(day,startDate, endDate) as counts from #temp
group by StartDate, endDate
) as a
-----------
88

(1 行受影响)

drop table #temp
子陌红尘 2009-06-26
  • 打赏
  • 举报
回复
[Quote=引用 17 楼 feixianxxx 的回复:]
ID 1 和2 隔的天数 还有3 和4隔的天数 都是相互相同 不是只取 ID 为1 3 或者 2 4么?
[/Quote]

根据分析楼主所提供的测试数据,第3条记录与第1、2两条重复的记录数据,在日期范围内存在一个交集,即 2009-04-01 --> 2009-04-12 ;故尔这三条记录可以被合并成一个大的时间区间,即 2009-03-14 --> 2009-05-01;这类问题归集为合并多个存在交集的时间区间或数字区间的问题。
lg3605119 2009-06-26
  • 打赏
  • 举报
回复

if object_id('tb') is not null
drop table tb
go
create table tb(id int, startDate datetime,endDate datetime)
go
insert into tb
select 1, '2009-4-1', '2009-5-1' union all
select 2, '2009-4-1', '2009-5-1' union all
select 3, '2009-3-14', '2009-4-12' union all
select 4, '2009-6-1', '2009-6-30'
go

create table #(date datetime)
go

declare @num int
select @num = max(id) from tb
declare @i int
set @i = 1
while @i <= @num
begin
insert into #
select dateadd(day,b.number,a.startDate) from tb a ,master..spt_values b
where b.type = 'P' and dateadd(day,b.number,a.startDate)<=a.endDate and id = @i
set @i = @i+1
end

select count(1) as [时间总数] from (select distinct * from #)T
drop table tb,#

/*
79
*/
子陌红尘 2009-06-26
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 wuxiaoqqqq 的回复:]
引用 13 楼 libin_ftsafe 的回复:
引用 10 楼 wuxiaoqqqq 的回复:
是enddate-startdate


8楼的SQL合并了多个存在交集的时间段;9楼的SQL在其基础上统计了不重复的天数。



恩,我研究一下你两个not exist的用法,对SQL求交集这块一直就不怎么会用。
[/Quote]

子查询 a 用于查找在所有的时间段记录中,不被别的时间段包括的时间段起点(即始终是起始时间点);
子查询 b 用于查找在所有的时间段记录中,不被别的时间段包括的时间段终端(即始终是终止时间点)。
feixianxxx 2009-06-26
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 wuxiaoqqqq 的回复:]
引用 13 楼 libin_ftsafe 的回复:
引用 10 楼 wuxiaoqqqq 的回复:
是enddate-startdate


8楼的SQL合并了多个存在交集的时间段;9楼的SQL在其基础上统计了不重复的天数。



恩,我研究一下你两个not exist的用法,对SQL求交集这块一直就不怎么会用。
[/Quote]
ID 1 和2 隔的天数 还有3 和4隔的天数 都是相互相同 不是只取 ID 为1 3 或者 2 4么?
feixianxxx 2009-06-26
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 wuxiaoqqqq 的回复:]
引用 13 楼 libin_ftsafe 的回复:
引用 10 楼 wuxiaoqqqq 的回复:
是enddate-startdate


8楼的SQL合并了多个存在交集的时间段;9楼的SQL在其基础上统计了不重复的天数。



恩,我研究一下你两个not exist的用法,对SQL求交集这块一直就不怎么会用。
[/Quote]
不是59天么?
wuxiaoqqqq 2009-06-26
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 libin_ftsafe 的回复:]
引用 10 楼 wuxiaoqqqq 的回复:
是enddate-startdate



8楼的SQL合并了多个存在交集的时间段;9楼的SQL在其基础上统计了不重复的天数。
[/Quote]

恩,我研究一下你两个not exist的用法,对SQL求交集这块一直就不怎么会用。
feixianxxx 2009-06-26
  • 打赏
  • 举报
回复
-- =========================================
-- -----------t_mac 小编-------------
---希望有天成为大虾----
-- =========================================

IF OBJECT_ID('tb') IS NOT NULL
DROP TABLE tb
GO
CREATE TABLE tb(id int,startdate datetime,enddate datetime)
go
insert into tb
select 1,'2009-4-1','2009-5-1' union all
select 2,'2009-4-1','2009-5-1' union all
select 3,'2009-3-14','2009-4-12' union all
select 4,'2009-6-1','2009-6-30'
go
select SUM(DATEDIFF(dd,startdate,enddate))
from(
select * from tb t where not exists
(select * from tb where id>t.id and DATEDIFF(DD,t.startdate,t.enddate)=DATEDIFF(DD,startdate,enddate))) t

/*------------
59
-------*/
子陌红尘 2009-06-26
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 wuxiaoqqqq 的回复:]
是enddate-startdate
[/Quote]

8楼的SQL合并了多个存在交集的时间段;9楼的SQL在其基础上统计了不重复的天数。
wuxiaoqqqq 2009-06-26
  • 打赏
  • 举报
回复
谢谢大家
子陌红尘(retired)是结果是对的。
我先研究一下他的代码。
ai_li7758521 2009-06-26
  • 打赏
  • 举报
回复
declare @t1 table(id int,StartDate datetime,EndDate datetime)
insert @t1
select 1, '2009-4-1' , '2009-5-1' union all
select 2, '2009-4-1' , '2009-5-1' union all
select 3, '2009-3-14', '2009-4-12' union all
select 4, '2009-6-1' , '2009-6-30'

select days=sum(datediff(dd,StartDate,EndDate))
from (select distinct StartDate,EndDate from @t1) A

days
-----------
88

(1 行受影响)
wuxiaoqqqq 2009-06-26
  • 打赏
  • 举报
回复
是enddate-startdate
子陌红尘 2009-06-26
  • 打赏
  • 举报
回复
declare @t table(ID int,SDate datetime,EDate datetime)
insert into @t select 1,'2009-04-01','2009-05-01'
insert into @t select 2,'2009-04-01','2009-05-01'
insert into @t select 3,'2009-03-14','2009-04-12'
insert into @t select 4,'2009-06-01','2009-06-30'

select
sum(n.Date) as Days
from
(select
datediff(dd,a.SDate,min(b.EDate)+1) as Date
from
(select SDate from @t t where not exists(select 1 from @t where SDate<t.SDate and EDate>=t.SDate)) a,
(select EDate from @t t where not exists(select 1 from @t where SDate<=t.EDate and EDate>t.EDate)) b
where
a.SDate<=b.EDate
group by
a.SDate) n

/*
Days
-----------
79
*/
子陌红尘 2009-06-26
  • 打赏
  • 举报
回复
declare @t table(ID int,SDate datetime,EDate datetime)
insert into @t select 1,'2009-04-01','2009-05-01'
insert into @t select 2,'2009-04-01','2009-05-01'
insert into @t select 3,'2009-03-14','2009-04-12'
insert into @t select 4,'2009-06-01','2009-06-30'

select
a.SDate,min(b.EDate) as EDate
from
(select SDate from @t t where not exists(select 1 from @t where SDate<t.SDate and EDate>=t.SDate)) a,
(select EDate from @t t where not exists(select 1 from @t where SDate<=t.EDate and EDate>t.EDate)) b
where
a.SDate<=b.EDate
group by
a.SDate

/*

SDate EDate
------------------------------------------------------ ------------------------------------------------------
2009-03-14 00:00:00.000 2009-05-01 00:00:00.000
2009-06-01 00:00:00.000 2009-06-30 00:00:00.000
*/
ai_li7758521 2009-06-26
  • 打赏
  • 举报
回复
select days=sum(datediff(dd,StartDate,EndDate))
from (select distinct * from tb) A
加载更多回复(6)

27,582

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 应用实例
社区管理员
  • 应用实例社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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