计算没有临时年表的活动项目/年份

时间:2015-11-07 15:08:11

标签: sql sql-server sql-server-2008 firebird

具有以下记录结构:

<item> | <start>    | <stop>
Item-A | 2013-04-05 | 2014-06-07
Item-B | 2012-06-07 | 2015-03-07

是否可以使用SQL查询(在MS-SQL&gt; = 2008和Firebird&gt; = 2.5)每年有多少项有效?结果应该是:

2012 | 1
2013 | 2
2014 | 2
2015 | 1

我使用了包含系列(1900..2100)的temorary表,并使用BETWEEN和extract(year ..)连接原始表和临时表。但我正在寻找更好的解决方案而不使用额外的表格。

2 个答案:

答案 0 :(得分:1)

这符合您的要求。

select Years.[Year],
       count(1) [Count]
from MyTable mt
join (select distinct(year(start)) as [Year] 
      from MyTable

      union 

      select distinct(year(stop)) 
      from MyTable

      union 

      select year(getdate())
      from MyTable 
      where exists 
          (select 1 
           from MyTable 
           where stop is null)) as Years
on Years.[Year] between Year(mt.start) and Year(isnull(mt.stop, getdate()))
group by Years.[Year]
order by Years.[Year]

答案 1 :(得分:0)

这就是我使用辅助函数的方法。

declare @StartMin datetime
declare @StopMax datetime

select @StartMin = min(start),
@StopMax = max(isnull(stop, getdate()))
from MyTable

select Years.[Year],
count(1) [Count]
from MyTable mt
join [dbo].[YearsBetween](@StartMin, @StopMax) as Years
on Years.[Year] between Year(mt.start) and Year(isnull(mt.stop, getdate()))
group by Years.[Year]
order by Years.[Year]

这是辅助函数,我有很多它们,DatesBetween,MonthsBetween,NumbersBetween等。

create function [dbo].[YearsBetween](@Start datetime, @Stop datetime)
returns @Years TABLE
(
[Year] int
)
begin
declare @StartYear int
declare @StopYear int

set @StartYear = year(@Start)
set @StopYear = year(@Stop)

while(@StartYear <= @StopYear)
begin
    insert into @Years 
    values(@StartYear)

    set @StartYear = @StartYear + 1
end

return;
end