【问题标题】:How to handle leap year in sql queries如何在sql查询中处理闰年
【发布时间】:2012-03-19 03:18:12
【问题描述】:

我的示例查询:

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))

如果您看到我在 where 子句中使用 (yr - 1) 并且这会在 2011 年、2010 年抛出 date out of range 错误,有没有一种好方法可以在查询中检查闰年并使用正确的日期?

【问题讨论】:

  • 为什么不在示例查询中使用 datadd 或 datediff ,而这就是标题中的内容?看起来 Dateadd 会按照 Diego 的回答做到这一点......我们在这里遗漏了什么吗?

标签: .net sql sql-server sql-server-2008 sql-server-2005


【解决方案1】:

尝试将 yr - 1 替换为:

DATEADD(year,-1,yr )

【讨论】:

  • 我的问题是关于闰年日期,没有 02/29/2011 日期,我想看看是否有好的方法来检查这种情况。
  • @rs.:Diego 的观点是,如果你这样做 SELECT DATEADD(year, -1, GETDATE()),它今天可以正常工作并给出 2011-02-28。您遇到问题的唯一原因是您在代码中声称存在 2011-02-29(假设 f.completedt 是 Datetime,因此您构造的字符串被解释为日期)。
  • 抱歉不清楚,我没有使用 dateadd,因为我可能有随机年份 foo 表和 yr 表,我不能使用 DateAdd(year -1, getdate())
  • @rs。 - 我同意克里斯和迭戈的观点。您遇到了问题,因为您正在使用字符串操作来进行日期算术。如果您使用现有的日期功能,您会发现更多的功能/灵活性和更少的问题。例如,您永远不会生成非法日期,或者给定“月初”,您可以使用DATEADD(month, 1, start_of_month) - 1 获得“月末”。你真的应该永远需要使用字符串...
  • @rs.:我给出了一个使用 DateAdd 的答案,并根据目标年份计算出要加/减多少年。正如 Dems 所说,您永远不需要字符串操作。只要弄清楚你需要在函数方面做什么,你几乎总能以某种方式做到这一点(尽管它并不总是看起来很漂亮。此外,作为使用字符串作为日期的指针,iso 格式 2011-02-29 是很多更好的使用,因为它是非模糊的。当月的日期为 12 或更少时,美式日期格式取决于服务器设置(即您的代码在英国服务器上可能有不同的结果)。
【解决方案2】:

根据您对其他答案的 cmets,这些方面的内容如何:

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)

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

【讨论】:

  • 谢谢你,我根据我的要求调整了你的解决方案,它奏效了,这个讨论帮助我理解了比我想要的更多的东西。
  • 酷。很高兴您的理解以及正确的答案。 [在这里插入关于教人钓鱼的谚语]
【解决方案3】:

如果你想知道年份是否是闰年,那么这段代码可以帮助你。

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; 

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

【讨论】:

  • 虽然这回答了年份是否是闰年的问题,但实际问题最好通过接受的答案来回答。
猜你喜欢
  • 1970-01-01
  • 2011-07-16
  • 2022-12-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多