我需要在sql下执行12个月(4月12日,5月12日,6月12日... 4月13日) 但是不想多次执行或重写我的sql。试图确定是否有办法做这个作为递归cte的一部分..需要确保月份日期是正确的(每隔一个月30/31天,2月有28天)。
这是我的sql
Select
--Month of Apr 2012
(Select 1.0 * 100 *
(
Select COUNT(*)
from B b
left outer join F f on f.id = b.id
Where f.date1 < '05/01/2012' and
(f.date2 between '04/01/2012' and '04/30/2012' or f.date2 is Null)
)
/
(Select COUNT(*)
from f
Where date1 < '05/01/2012' and
(date2 between '04/01/2013' and '04/30/2013' or date2 is Null)) as 'Apr 2012',
--Month of May 2012
(Select 1.0 * 100 *
(
Select COUNT(*)
from B b
left outer join F f on f.id = b.id
Where f.date1 < '06/01/2012' and
(f.date2 between '05/01/2012' and '05/31/2012' or f.date2 is Null)
)
/
(Select COUNT(*)
from f
Where date1 < '06/01/2012' and
(date2 between '05/01/2013' and '05/31/2013' or date2 is Null)) as 'May 2012'
答案 0 :(得分:1)
试试这个 -
DECLARE @DateFrom DATETIME
SELECT @DateFrom = '20130101'
;WITH cte AS
(
SELECT
t.[date]
, date_next
, [month] = MONTH(t.[date])
, [year] = YEAR(t.[date])
FROM (
SELECT
[date] = DATEADD(MONTH, sv.number, @DateFrom)
, date_next = DATEADD(MONTH, sv.number + 1, @DateFrom)
FROM [master].dbo.spt_values sv
WHERE sv.[type] = 'p'
AND sv.number BETWEEN 0 AND 11
) t
)
SELECT
cte.[date]
, value = 100 * t2.cnt / t.cnt
FROM cte
OUTER APPLY (
SELECT cnt = COUNT(1)
FROM f
WHERE f.date1 < cte.date_next
AND cte.[month] = ISNULL(MONTH(f.date2), cte.[month])
AND cte.[year] = ISNULL(YEAR(f.date2), cte.[year])
) t
OUTER APPLY (
SELECT cnt = COUNT(1)
FROM b
LEFT JOIN f on f.id = b.id
WHERE f.date1 < cte.date_next
AND cte.[month] = ISNULL(MONTH(f.date2), cte.[month])
AND cte.[year] = ISNULL(YEAR(f.date2), cte.[year])
) t2
答案 1 :(得分:0)
尝试此操作以生成所有月份的第一天和最后一天。另一种解决方案是使用包含这些信息的静态表。之后,您可以直接加入此表,并根据您的需要进行分组。
另外我不明白1.0 * 100如果你想确定你没有int那里你可以尝试100。
declare @year varchar(4)
select @year=convert(varchar(4),year(getdate()))
create table #months
(
FirstDay datetime
,LastDay datetime
)
declare @k int,@date datetime
select @k=1
while @k<=12
begin
select @date=convert(datetime,@year+right('0'+convert(varchar(2),@k),2)+'01',112)
insert into #months
select @date
,dateadd(d,-1,dateadd(m,1,@date))
set @k=@k+1
end
select *
from #months
drop table #months