2月29日与去年2月28日相比

时间:2012-03-01 14:12:59

标签: sql tsql

我有一个存储过程可以提取数据并在Date上加入去年的数据。问题是当前年度数据无法加入,因为2011年2月29日没有。有其他人遇到过这个问题吗?任何人对如何解决它有任何想法?

这是存储过程:

SELECT 
--b.Date_Rep AS Date_Rep,
SUM(b.AccountsCreatedThisYear) AS AccountsCreatedThisYearTot,
SUM(a.AccountsCreatedThisYear) AS AccountsCreatedLastYearTot,   

FROM Report2011.dbo.T_Report_01 b  WITH (NOLOCK) --This year    
LEFT JOIN Report2011.dbo.T_Report_01 a WITH (NOLOCK) ON DATEADD(yyyy,-1,b.Date_Rep) = a.date_rep --Last year
WHERE (a.Date_Rep BETWEEN DATEADD(year, -1,@StartDate) AND DATEADD(year, -1,@EndDate))

4 个答案:

答案 0 :(得分:4)

对于初学者,我不会对左连接外侧的表中的列执行where子句。试试这个,而不是:

SELECT SUM(b.AccountsCreatedThisYear) AS AccountsCreatedThisYearTot,
       SUM(a.AccountsCreatedThisYear) AS AccountsCreatedLastYearTot,   
FROM Report2011.dbo.T_Report_01 b  WITH (NOLOCK) --This year    
LEFT JOIN Report2011.dbo.T_Report_01 a WITH (NOLOCK) 
       ON DATEADD(yyyy,-1,b.Date_Rep) = a.date_rep --Last year
WHERE b.Date_Rep BETWEEN @StartDate AND @EndDate

答案 1 :(得分:1)

尝试使用FULL OUTER JOIN代替LEFT JOIN并使用COALESCE

SUM(COALESCE(b.AccountsCreatedThisYear, 0)) AS AccountsCreatedThisYearTotSUM(COALESCE(a.AccountsCreatedThisYear, 0)) AS AccountsCreatedLastYearTot

所以当日期不匹配时,你要避免使用NULL。

答案 2 :(得分:0)

    declare @29Feb datetime = convert(datetime,'2012/02/29')
    declare @28Feb datetime = convert(datetime,'2012/02/28')

 select case when 
             dateadd(yy,-1,@29Feb) = dateadd(yy,-1,@28Feb)
             then 1 
             else 0 end

这个选择语句输出1,所以实际上2月29日和2月28日的日期在过去的一年,2月28日只有一个相应的日期。

现在,您正在为不同年份的两个期间进行总和,因为第一个期间比当前期间少1天。
有人会如何回答以下问题:

 "How many accounts have been created in the last year's February and how many this year?" 

一个二月有28天而另一个有29天是否重要?我不相信,参考是2月,而不是日子。

所以我看到这个查询有两个问题:

  • 今年可能有一天没有创建帐户,但在去年同期,有些帐户确实存在,所以左边的连接没有抓住去年的帐号
  • 对于今年的两个不同的日期,28和29只对应一天,28,所以这一次相加两次。


 SELECT     (SUM(b.AccountsCreatedThisYear)
    FROM Report2011.dbo.T_Report_01 WITH (NOLOCK) --This year
    WHERE Date_Rep BETWEEN @StartDate and @EndDate ) as AccountsCreatedThisYearTot,

    (SUM(b.AccountsCreatedThisYear)
    FROM Report2011.dbo.T_Report_01 WITH (NOLOCK) -- Last Year
    WHERE Date_Rep BETWEEN DATEADD(year, -1,@StartDate) AND DATEADD(year, -1,@EndDate)) as AccountsCreatedLastYearTot

答案 3 :(得分:0)

去年没有2月29日,但3月1日是365天前,2月28日是366天前。

SELECT SUM(b.AccountsCreatedThisYear) AS AccountsCreatedThisYearTot,
   SUM(a.AccountsCreatedThisYear) AS AccountsCreatedLastYearTot,   
FROM Report2011.dbo.T_Report_01 b  WITH (NOLOCK) --This year    
LEFT JOIN Report2011.dbo.T_Report_01 a WITH (NOLOCK) 
   ON DATEADD(dd,-365,b.Date_Rep) = a.date_rep --Last year
WHERE b.Date_Rep BETWEEN @StartDate AND @EndDate 

+1 Mark Ba​​nnister因为我使用了他的语法