【问题标题】:Get items that were created exactly one, two, n... years ago获取恰好在一、二、几年前创建的项目
【发布时间】:2014-10-10 13:09:50
【问题描述】:

我应该从某个表中选择至少在一年前创建的项目 - 与今天相同的月份和日期。因此,在 2011 年 10 月 10 日、2013 年 10 月 10 日创建的项目将适合,但不适用于 2014 年 10 月 10 日。

以下查询工作正常,但也许有更优雅的方式?提前致谢。

select * from myTable 
where 
    DATEPART(MONTH, CreatedOn) = DATEPART(MONTH, GETDATE()) -- item was created at the same month
    and DATEPART(DAY, CreatedOn) = DATEPART(DAY, GETDATE()) -- and at the same day
    and DATEDIFF(YEAR, CreatedOn, GETDATE()) >= 1           -- and at least one year ago

【问题讨论】:

  • 这将是一个常见的查询还是更罕见/一次性的事情? 2 月 29 日是否应该有任何特殊处理(考虑闰年和非闰年)?
  • 仅供参考。如果您在 SELECT 之前声明这些日期值,SQL Server 的执行速度会快得多。将 DATEPART(MONTH,GETDATE())DATEPART(DAY,GETDATE()) 之类的内容设置为声明并在您的 select 语句中传递该变量,SQL 的性能将大大提高。
  • @Jason 是的,谢谢
  • @Damien_The_Unbeliever 每天都会执行一次,每天一次。嗯,我忘记了2月29日……那些29日的记录,如果今年2月只有28天的话,也应该是出席事件

标签: sql sql-server-2008 datetime


【解决方案1】:

我会(如果可能)将表格更改为额外的computed column,定义为:

DATEADD(year,DATEDIFF(year,CreatedOn,0),CONVERT(date,CreatedOn))

比如说,叫AnniversaryDate。这具有将日期“标准化”为 1900 年的效果。这也将 2 月 29 日与 2 月 28 日视为相同(两者都被标准化为 28 日)。

您现在创建了一个index on this computed column,可以在其中快速轻松地进行搜索。您使用相同的公式将GETDATE() 转换为“标准化”日期以搜索此数据。您现在要做的就是排除今年发生的结果,这应该像一个额外的过滤器一样简单。所以你的最终查询是:

AnniversaryDate = DATEADD(year,DATEDIFF(year,GETDATE(),0),
                  CONVERT(date,GETDATE())) and
CreatedOn < CONVERT(date,GETDATE())

(我可能会在 AnniversaryDate 和 CreatedOn 上创建一个索引,以最大限度地从该查询中受益)。

【讨论】:

    猜你喜欢
    • 2011-01-31
    • 2021-10-07
    • 1970-01-01
    • 2018-06-06
    • 1970-01-01
    • 2012-03-04
    • 1970-01-01
    • 2014-11-25
    • 1970-01-01
    相关资源
    最近更新 更多