我有这个查询,它选择跨越iMAXYears的所有记录,直到2012年11月30日:
SELECT sum([AllocatedAmount]) as total,
datediff(day,transactiondate,'30 Nov 2012') / DaysInyear AS YearDiff
FROM tblGroups
AND datediff(day,transactiondate, '30 Nov 2012') / DaysInyear < iMaxYears
AND not transactiondate > '30 Nov 2012'
GROUP BY g.groupdescription, nominal,
datediff(day,transactiondate, '30 Nov 2012') / DaysInyear
出于本问题的目的,2012年11月30日是硬编码的(变量名= lMaxDate),iMaxYears是3
我的问题是,DaysInYear的值通常为365,但在闰年中的值为366.
在2012年的闰年,由于2012年2月29日,上述声明并未在2011年12月1日回升。
我知道
DaysInYear=(CASE WHEN (year % 4 = 0 AND year % 100 <> 0)
OR year % 400 = 0 then 366 else 365)
Currently DaysInYear = 365.
我应该创建一个功能
DaysInYear(lYear) where you pass in a year (lYear)
and it returns 365 or 366?
问题是我无法通过Year(transactiondate),因为年份将始终跨越2年的部分时间,iMaxYears意味着我们可以在结果集中有4个年度周期。
有什么想法吗?感谢
答案 0 :(得分:0)
如果您只使用该case语句代替DaysInYear变量怎么办?
SELECT sum([AllocatedAmount]) as total,
datediff(day,transactiondate,'30 Nov 2012') / CASE WHEN (year % 4 = 0 AND year % 100 <> 0)
OR year % 400 = 0 then 366 else 365 end AS YearDiff
FROM tblGroups
AND datediff(day,transactiondate, '30 Nov 2012') / CASE WHEN (year % 4 = 0 AND year % 100 <> 0)
OR year % 400 = 0 then 366 else 365 end < iMaxYears
AND not transactiondate > '30 Nov 2012'
GROUP BY g.groupdescription, nominal,
datediff(day,transactiondate, '30 Nov 2012') / CASE WHEN (year % 4 = 0 AND year % 100 <> 0)
OR year % 400 = 0 then 366 else 365 end
只要年份中的天数值基于相关交易日期,您就应该明确。
答案 1 :(得分:0)
如果您从transactionDate中删除29天和10个月,则可以将截止点移至1月1日。这样,DATEADD会为您减去适当的天数。
CREATE FUNCTION yearDiff(@maxDate DATE, @transactionDate DATE)
RETURNS INT AS
BEGIN
DECLARE @dayDiff INT
DECLARE @monthDiff INT
-- Determine how many months and days @maxDate is from the first of january
SET @monthDiff = 1 - DATEPART(MONTH, @maxDate)
SET @dayDiff = 1 - DATEPART(DAY, @maxDate)
-- Determine how many years away from @maxDate the transaction is
RETURN DATEDIFF(YEAR,
DATEADD(MONTH,
@monthDiff,
DATEADD(DAY,
@dayDiff,
@transactionDate)
),
@maxDate
)
END
我认为你的选择会是这样的:
SELECT
sum(amount) [total],
dbo.yearDiff(@maxDate, transactionDate) [yearDiff]
FROM tblGroups
WHERE transactionDate <= @maxDate
AND dbo.yearDiff(@maxDate, transactionDate) <= @iMaxYears
GROUP BY dbo.yearDiff(@maxDate, transactionDate)
http://sqlfiddle.com/#!6/54c2d/2
优点是它既美观又可读,而且你没有神奇的数字。它不是特别有效,如果有很多事务,你会想要内联函数调用或者为yearDiff添加一个计算列。