具有以下记录结构:
<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 ..)连接原始表和临时表。但我正在寻找更好的解决方案而不使用额外的表格。
答案 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