22,210
社区成员
发帖
与我相关
我的任务
分享
create table [tb]([tduty] varchar(4),[tem_num] varchar(6),[tstartd] datetime,[tendd] datetime)
insert [tb]
select '951D','500236','2005-01-12 00:00:00.000','2005-05-01 00:00:00.000' union all
select '951D','600751','2005-01-16 00:00:00.000','2005-05-20 00:00:00.000' union all
select '951D','000329','2005-01-28 00:00:00.000','2005-06-03 00:00:00.000' union all
select '951D','000329','2005-06-04 00:00:00.000','2005-10-13 00:00:00.000' union all
select '951D','600189','2005-08-21 00:00:00.000','2005-11-28 00:00:00.000' union all
select '951C','003640','2004-01-01 00:00:00.000','2005-01-25 00:00:00.000' union all
select '951C','000213','2004-01-10 00:00:00.000','2005-01-28 00:00:00.000' union all
select '951C','005567','2004-01-29 00:00:00.000','2005-01-16 00:00:00.000' union all
select '951C','600055','2004-05-21 00:00:00.000','2005-04-14 00:00:00.000' union all
select '951C','000692','2004-05-31 00:00:00.000','2005-04-01 00:00:00.000' union all
select '941D','005671','2004-03-19 00:00:00.000','2005-01-12 00:00:00.000' union all
select '941D','004873','2004-04-01 00:00:00.000','2005-01-05 00:00:00.000'
create table t2(id int, tduty varchar(10), [year] int, cnt int)
go
declare @tduty1 varchar(10),@tduty2 varchar(10),@tstartd1 datetime,@tstartd2 datetime ,@tendd1 datetime , @tendd2 datetime;
declare @id as int
set @id = 0
set @tduty1 = ''
set @tduty2 = ''
set @tstartd1 = getdate()
set @tstartd2 = getdate()
set @tendd1 = getdate()
set @tendd2 = getdate()
declare cur cursor fast_forward for
select tduty,tstartd,tendd from tb order by tduty,tstartd,tendd;
open cur;
fetch next from cur into @tduty1,@tstartd1,@tendd1;
while @@fetch_status=0
begin
if @tduty1 = @tduty2
begin
if @tstartd1 between @tstartd2 and @tendd2 or @tendd1 between @tstartd2 and @tendd2 or
@tstartd2 between @tstartd1 and @tendd1 or @tendd2 between @tstartd1 and @tendd1
update t2 set [year] = year(@tendd1) , cnt = cnt + 1 where id = @id
else
begin
set @id = @id + 1
insert t2 select @id , @tduty1 , year(@tendd1) , 1
end
end
else
begin
set @id = @id + 1
insert t2 select @id , @tduty1 , year(@tendd1) , 1
end
set @tduty2 = @tduty1
set @tstartd2 = @tstartd1
set @tendd2 = @tendd1
fetch next from cur into @tduty1,@tstartd1,@tendd1;
end
close cur;
deallocate cur;
select * from t2 order by id
drop table tb , t2
/*
id tduty year cnt
----------- ---------- ----------- -----------
1 941D 2005 2
2 951C 2005 5
3 951D 2005 3
4 951D 2005 2
(所影响的行数为 4 行)
*/
create table [tb]([tduty] varchar(4),[tem_num] varchar(6),[tstartd] datetime,[tendd] datetime)
insert [tb]
select '951D','500236','2005-01-12 00:00:00.000','2005-05-01 00:00:00.000' union all
select '951D','600751','2005-01-16 00:00:00.000','2005-05-20 00:00:00.000' union all
select '951D','000329','2005-01-28 00:00:00.000','2005-06-03 00:00:00.000' union all --这里和下面一条出现交叉.
select '951D','000329','2005-06-03 00:00:00.000','2005-10-13 00:00:00.000' union all
select '951D','600189','2005-08-21 00:00:00.000','2005-11-28 00:00:00.000' union all
select '951C','003640','2004-01-01 00:00:00.000','2005-01-25 00:00:00.000' union all
select '951C','000213','2004-01-10 00:00:00.000','2005-01-28 00:00:00.000' union all
select '951C','005567','2004-01-29 00:00:00.000','2005-01-16 00:00:00.000' union all
select '951C','600055','2004-05-21 00:00:00.000','2005-04-14 00:00:00.000' union all
select '951C','000692','2004-05-31 00:00:00.000','2005-04-01 00:00:00.000' union all
select '941D','005671','2004-03-19 00:00:00.000','2005-01-12 00:00:00.000' union all
select '941D','004873','2004-04-01 00:00:00.000','2005-01-05 00:00:00.000'
create table t2(tduty varchar(10), [year] int, cnt int)
go
declare @tduty1 varchar(10),@tduty2 varchar(10),@tstartd1 datetime,@tstartd2 datetime ,@tendd1 datetime , @tendd2 datetime;
set @tduty1 = ''
set @tduty2 = ''
set @tstartd1 = getdate()
set @tstartd2 = getdate()
set @tendd1 = getdate()
set @tendd2 = getdate()
declare cur cursor fast_forward for
select tduty,tstartd,tendd from tb order by tduty,tstartd,tendd;
open cur;
fetch next from cur into @tduty1,@tstartd1,@tendd1;
while @@fetch_status=0
begin
if @tduty1 = @tduty2
begin
if @tstartd1 between @tstartd2 and @tendd2 or @tendd1 between @tstartd2 and @tendd2 or
@tstartd2 between @tstartd1 and @tendd1 or @tendd2 between @tstartd1 and @tendd1
update t2 set [year] = year(@tendd1) , cnt = cnt + 1 where tduty = @tduty1 and [year] = year(@tendd2)
else
begin
insert t2 select @tduty1 , year(@tendd1) , 1
end
end
else
begin
insert t2 select @tduty1 , year(@tendd1) , 1
end
set @tduty2 = @tduty1
set @tstartd2 = @tstartd1
set @tendd2 = @tendd1
fetch next from cur into @tduty1,@tstartd1,@tendd1;
end
close cur;
deallocate cur;
select * from t2 order by tduty , [year]
drop table tb , t2
/*
tduty year cnt
---------- ----------- -----------
941D 2005 2
951C 2005 5
951D 2005 5
(所影响的行数为 3 行)
*/
create table [tb]([tduty] varchar(4),[tem_num] varchar(6),[tstartd] datetime,[tendd] datetime)
insert [tb]
select '951D','500236','2005-01-12 00:00:00.000','2005-05-01 00:00:00.000' union all
select '951D','600751','2005-01-16 00:00:00.000','2005-05-20 00:00:00.000' union all
select '951D','000329','2005-01-28 00:00:00.000','2005-06-03 00:00:00.000' union all
select '951D','000329','2005-06-04 00:00:00.000','2005-10-13 00:00:00.000' union all
select '951D','600189','2005-08-21 00:00:00.000','2005-11-28 00:00:00.000' union all
select '951C','003640','2004-01-01 00:00:00.000','2005-01-25 00:00:00.000' union all
select '951C','000213','2004-01-10 00:00:00.000','2005-01-28 00:00:00.000' union all
select '951C','005567','2004-01-29 00:00:00.000','2005-01-16 00:00:00.000' union all
select '951C','600055','2004-05-21 00:00:00.000','2005-04-14 00:00:00.000' union all
select '951C','000692','2004-05-31 00:00:00.000','2005-04-01 00:00:00.000' union all
select '941D','005671','2004-03-19 00:00:00.000','2005-01-12 00:00:00.000' union all
select '941D','004873','2004-04-01 00:00:00.000','2005-01-05 00:00:00.000'
create table t2(tduty varchar(10), [year] int, cnt int)
go
declare @tduty1 varchar(10),@tduty2 varchar(10),@tstartd1 datetime,@tstartd2 datetime ,@tendd1 datetime , @tendd2 datetime;
set @tduty1 = ''
set @tduty2 = ''
set @tstartd1 = getdate()
set @tstartd2 = getdate()
set @tendd1 = getdate()
set @tendd2 = getdate()
declare cur cursor fast_forward for
select tduty,tstartd,tendd from tb order by tduty,tstartd,tendd;
open cur;
fetch next from cur into @tduty1,@tstartd1,@tendd1;
while @@fetch_status=0
begin
if @tduty1 = @tduty2
begin
if @tstartd1 between @tstartd2 and @tendd2 or @tendd1 between @tstartd2 and @tendd2 or
@tstartd2 between @tstartd1 and @tendd1 or @tendd2 between @tstartd1 and @tendd1
update t2 set [year] = year(@tendd1) , cnt = cnt + 1 where tduty = @tduty1 and [year] = year(@tendd2)
else
begin
insert t2 select @tduty1 , year(@tendd1) , 1
end
end
else
begin
insert t2 select @tduty1 , year(@tendd1) , 1
end
set @tduty2 = @tduty1
set @tstartd2 = @tstartd1
set @tendd2 = @tendd1
fetch next from cur into @tduty1,@tstartd1,@tendd1;
end
close cur;
deallocate cur;
select * from t2 order by tduty , [year]
drop table tb , t2
/*
tduty year cnt
---------- ----------- -----------
941D 2005 2
951C 2005 5
951D 2005 4
951D 2005 2
(所影响的行数为 4 行)
*/
create table [tb]([tduty] varchar(4),[tem_num] varchar(6),[tstartd] datetime,[tendd] datetime)
insert [tb]
select '951D','500236','2005-01-12 00:00:00.000','2005-05-01 00:00:00.000' union all
select '951D','600751','2005-01-16 00:00:00.000','2005-05-20 00:00:00.000' union all
select '951D','000329','2005-01-28 00:00:00.000','2005-06-03 00:00:00.000' union all
select '951D','000329','2005-06-03 00:00:00.000','2005-10-13 00:00:00.000' union all
select '951D','600189','2005-08-21 00:00:00.000','2005-11-28 00:00:00.000' union all
select '951C','003640','2004-01-01 00:00:00.000','2005-01-25 00:00:00.000' union all
select '951C','000213','2004-01-10 00:00:00.000','2005-01-28 00:00:00.000' union all
select '951C','005567','2004-01-29 00:00:00.000','2005-01-16 00:00:00.000' union all
select '951C','600055','2004-05-21 00:00:00.000','2005-04-14 00:00:00.000' union all
select '951C','000692','2004-05-31 00:00:00.000','2005-04-01 00:00:00.000' union all
select '941D','005671','2004-03-19 00:00:00.000','2005-01-12 00:00:00.000' union all
select '941D','004873','2004-04-01 00:00:00.000','2005-01-05 00:00:00.000'
go
--需要使用一个临时表来拆分时间。
SELECT TOP 8000 id = IDENTITY(int, 0, 1) INTO # FROM syscolumns a, syscolumns b
select tduty , max([year]) [year], count(1) cnt from
(
select distinct tduty,tem_num,year(tstartd + n.id) [year] from tb dt , # n where tstartd + n.id <= tendd
) t
group by tduty
order by tduty
drop table tb , #
/*
tduty year cnt
----- ----------- -----------
941D 2005 4
951C 2005 10
951D 2005 4
(所影响的行数为 3 行)
*/
---测试数据---
if object_id('[tb]') is not null drop table [tb]
go
create table [tb]([tduty] varchar(4),[tem_num] varchar(6),[tstartd] datetime,[tendd] datetime)
insert [tb]
select '951D','500236','2005-01-12 00:00:00.000','2005-05-01 00:00:00.000' union all
select '951D','600751','2005-01-16 00:00:00.000','2005-05-20 00:00:00.000' union all
select '951D','000329','2005-01-28 00:00:00.000','2005-06-03 00:00:00.000' union all
select '951D','000329','2005-06-03 00:00:00.000','2005-10-13 00:00:00.000' union all
select '951D','600189','2005-08-21 00:00:00.000','2005-11-28 00:00:00.000' union all
select '951C','003640','2004-01-01 00:00:00.000','2005-01-25 00:00:00.000' union all
select '951C','000213','2004-01-10 00:00:00.000','2005-01-28 00:00:00.000' union all
select '951C','005567','2004-01-29 00:00:00.000','2005-01-16 00:00:00.000' union all
select '951C','600055','2004-05-21 00:00:00.000','2005-04-14 00:00:00.000' union all
select '951C','000692','2004-05-31 00:00:00.000','2005-04-01 00:00:00.000' union all
select '941D','005671','2004-03-19 00:00:00.000','2005-01-12 00:00:00.000' union all
select '941D','004873','2004-04-01 00:00:00.000','2005-01-05 00:00:00.000'
---查询---
select tduty,tendd,sum(cnt) as cnt
from(
select tduty,tem_num,year(tendd) as tendd,count(1) as cnt
from tb
group by tduty,tem_num,year(tendd)
) t
group by tduty,tendd,cnt
order by tduty desc,cnt desc
---结果---
tduty tendd cnt
----- ----------- -----------
951D 2005 3
951D 2005 2
951C 2005 5
941D 2005 2
(所影响的行数为 4 行)