.net 如何在sql查询中处理闰年

.net 如何在sql查询中处理闰年,.net,sql,sql-server,sql-server-2008,sql-server-2005,.net,Sql,Sql Server,Sql Server 2008,Sql Server 2005,我的示例查询: declare @todaysdate datetime = getdate() select * from foo f WHERE f.completedt < (CAST(MONTH(@todaysdate) AS VARCHAR) + '/' + CAST(DAY(@todaysdate) AS VARCHAR) + '/' + CAST(f.yr - 1 AS VARCHAR)) declare@todaysdate datetime=getdate() 从f

我的示例查询:

declare @todaysdate datetime = getdate()


select * from foo f
WHERE f.completedt < (CAST(MONTH(@todaysdate) AS VARCHAR) + '/' + CAST(DAY(@todaysdate) AS VARCHAR) + '/' + CAST(f.yr - 1 AS VARCHAR))
declare@todaysdate datetime=getdate()
从foo f中选择*
式中,f.completedt<(将月份(@todaysdate)转换为VARCHAR)+'/'+将日期(@todaysdate)转换为VARCHAR)+'/'+将f.yr-1转换为VARCHAR)

如果您看到我在where子句中使用了
(yr-1)
,并且这使
日期超出了2011年、2010年的范围
错误,是否有一种好方法可以在查询中检查闰年并使用正确的日期?

尝试将yr-1替换为:

DATEADD(year,-1,yr )

尝试将yr-1替换为:

DATEADD(year,-1,yr )

根据你对另一个答案的评论,按照以下几点如何:

DECLARE @testyear INT
SET @testyear = 2011

SELECT DATEADD(year, @testyear-DATEPART(YEAR, GETDATE()), GETDATE())
我们正在确定我们希望在输入的年份中加上或减去多少

因此,在你的情况下,我认为:

select * from foo f inner join @yrtable y on f.yr = y.year
WHERE f.completedt < DATEADD(year, @testyear-DATEPART(YEAR, @todaysdate), @todaysdate)
在f.yr=y.year上从foo f internal join@yrtable y中选择*
其中f.completedt

(假设我的减法是正确的。):)

根据您对另一个答案的评论,您认为以下几点如何:

DECLARE @testyear INT
SET @testyear = 2011

SELECT DATEADD(year, @testyear-DATEPART(YEAR, GETDATE()), GETDATE())
我们正在确定我们希望在输入的年份中加上或减去多少

因此,在你的情况下,我认为:

select * from foo f inner join @yrtable y on f.yr = y.year
WHERE f.completedt < DATEADD(year, @testyear-DATEPART(YEAR, @todaysdate), @todaysdate)
在f.yr=y.year上从foo f internal join@yrtable y中选择*
其中f.completedt

(假设我的减法是正确的。):)

如果您想知道年份是否是闰年,那么此代码可以帮助您

DECLARE 
   year integer := 2021; 
BEGIN 
   if((year mod(4) = 0) and (year mod(100) != 0) or (year mod(400) = 0)) then 
   dbms_output.put_line('Leap year');
   else
   dbms_output.put_line('not Leap year');
   end if;
   dbms_output.put_line('end');
END; 

参考它并在代码中进行必要的修改

如果您想确定年份是否为闰年,则此代码可以帮助您

DECLARE 
   year integer := 2021; 
BEGIN 
   if((year mod(4) = 0) and (year mod(100) != 0) or (year mod(400) = 0)) then 
   dbms_output.put_line('Leap year');
   else
   dbms_output.put_line('not Leap year');
   end if;
   dbms_output.put_line('end');
END; 

参考它并在代码中进行所需的修改

我的问题是关于闰年日期的,没有2011年2月29日的日期,我想看看是否有好的方法来检查这种情况。@rs:Diego的观点是,如果你选择了
DATEADD(year,-1,GETDATE())
,它今天工作正常,并给出2011-02-28。您遇到问题的唯一原因是因为您在代码中声明存在2011-02-29(假设f.completedt是日期时间,因此您构造的字符串被解释为日期)。很抱歉,不清楚,我没有使用dateadd,因为我可能有随机年份foo表和in yr表,我无法使用dateadd(year-1,getdate())@rs.-我同意Chris和Diego的观点。您遇到了问题,因为您使用字符串操纵来进行日期运算。如果您使用现有的日期函数,您将发现更强大/更灵活,问题更少。例如,您将永远不会生成非法日期,或者给定“月初”,您可以获得“月末”加上
DATEADD(第1个月,第1个月的开始)-1
。你真的不应该使用字符串…@rs:我给出了一个答案,使用DateAdd,并根据目标年份计算出要加/减多少年。正如Dems所说,你永远不应该需要字符串操作。只要计算出你需要在函数方面做什么,你几乎总能以某种方式做到(虽然它看起来并不总是很漂亮。同样,作为使用字符串作为日期的指针,iso格式2011-02-29是一种更好的格式,因为它不太适合使用。美式日期格式取决于月日为12或更少时的服务器设置(即您的代码在英国服务器上可能有不同的结果)。我的问题是关于闰年的日期,没有2011年2月29日的日期,我想看看是否有好的方法来检查这种情况。@rs:Diego的观点是,如果您选择
DATEADD(year,-1,GETDATE())
它在今天正常工作并给出2011-02-28。出现问题的唯一原因是因为您在代码中声明存在2011-02-29(假设f.completedt是日期时间,因此您构造的字符串被解释为日期)。很抱歉不清楚,我没有使用dateadd,因为我可能有随机年份foo表和yr表,并且我不能使用dateadd(year-1,getdate())@rs.-我同意Chris和Diego的观点。你遇到问题是因为你使用字符串操作来进行日期运算。如果你使用现有的日期函数,你会发现更强大/更灵活,问题更少。例如,你永远不会生成非法日期,或者给你一个“月初”,你可以得到“月底”“带有
DATEADD(月份,1,开始月份)-1
。你真的不应该使用字符串…@rs:我给出了一个答案,使用DateAdd,并根据目标年份计算出要加/减多少年。正如Dems所说,你永远不应该需要字符串操作。只要计算出你需要在函数方面做什么,你几乎总能以某种方式做到(虽然它看起来并不总是很漂亮。同样,作为使用字符串作为日期的指针,iso格式2011-02-29是一种更好的格式,因为它不太适合使用。美式日期格式取决于月日为12或更少时的服务器设置(即您的代码在英国服务器上可能有不同的结果)。如果标题中有datadd或datediff,为什么不在示例查询中使用它们?看起来Dateadd会按照Diego的回答完成这项任务…我们缺少什么吗?如果标题中有datadd或datediff,为什么不在示例查询中使用它们?看起来Dateadd会完成这项任务Diego回答的诀窍…我们这里缺少什么吗?谢谢,我根据我的要求调整了你的解决方案,它成功了,这次讨论帮助我理解了比我想要的更多。酷。很高兴你的理解以及正确的答案。[插入关于教人钓鱼的谚语]谢谢你,我根据我的要求调整了你的解决方案,它成功了,这次讨论帮助我理解了比我想要的更多的东西。酷。很高兴你的理解以及正确的答案。[Ins]