【问题标题】:GETDATE last month上个月 GETDATE
【发布时间】:2009-07-11 20:39:02
【问题描述】:

我正在尝试列出最后一个网站的统计信息。 我列出了过去 30 天;

CONVERT(VARCHAR(10), S.DATEENTERED, 101) 
  BETWEEN 
    CONVERT(VARCHAR(10), GETDATE()-30, 101) 
  AND 
    CONVERT(VARCHAR(10), GETDATE(), 101) 

这个月还有;

RIGHT(CONVERT(VARCHAR(10), S.DATEENTERED, 103), 7) = 
RIGHT(CONVERT(VARCHAR(10), GETDATE(), 103), 7)

但我不知道上个月要使用什么查询。我试过了;

RIGHT(CONVERT(VARCHAR(10), S.DATEENTERED, 103), 7) = 
RIGHT(CONVERT(VARCHAR(10), GETDATE()-1, 103), 7) 

没用。

【问题讨论】:

    标签: sql sql-server sql-server-2005


    【解决方案1】:

    在任何编程语言中使用日期总是一种乐趣,不排除 SQL。

    回答您的问题以查找上个月发生的所有记录

    select S.DATEENTERED
          ,*
      from sometable S
     where S.DATEENTERED
           between dateadd(mm, datediff(mm, 0, dateadd(MM, -1, getdate())), 0)
               and dateadd(ms, -3, dateadd(mm, datediff(mm, 0, dateadd(MM, -1, getdate())) + 1, 0))
    order by 1
    

    在某个时间范围内,扩展获取记录的最佳方法是利用 datediff 函数、dateadd 函数和 where 子句中的 between 条件。

    select 'howdy'
          ,getdate()
     where getdate()
           between dateadd(mm, 0, 0)
               and dateadd(ms, -3, dateadd(mm, datediff(mm, 0, dateadd(mm,-1,getutcdate())) + 1, 0))
    

    上面的代码将导致不返回任何记录,因为它正在检查今天的日期是否介于 1900-01-01 00:00:00.000 和上个月的最后可能记录日期(最后一天和 23:59 :59.997 - SQL Server DATETIME 列的分辨率最多为 3 毫秒)。

    以下代码将返回一条记录,因为我们要搜索的日期是一个月前。

    select 'howdy'
          ,dateadd(mm, -1, getdate())
     where dateadd(mm, -1, getdate())
           between dateadd(mm, 0, 0)
               and dateadd(ms, -3, dateadd(mm, datediff(mm, 0, dateadd(mm,-1,getutcdate())) + 1, 0))
    

    where 子句的分解:

    WHERE getdate()  -- date to check
    between dateadd(mm, 0, 0) -- begin date
    and dateadd(ms, -3, dateadd(mm, datediff(mm, 0, dateadd(mm,-1,getutcdate())) + 1, 0)) -- end date
    

    最后,可以通过这种方式确定各种日期,这是一个非常完整的列表:

    select dateadd(mm, 0, 0) as BeginningOfTime
          ,dateadd(dd, datediff(dd, 0, getdate()), 0) as Today
          ,dateadd(wk, datediff(wk, 0, getdate()), 0) as ThisWeekStart
          ,dateadd(mm, datediff(mm, 0, getdate()), 0) as ThisMonthStart
          ,dateadd(qq, datediff(qq, 0, getdate()), 0) as ThisQuarterStart
          ,dateadd(yy, datediff(yy, 0, getdate()), 0) as ThisYearStart
          ,dateadd(dd, datediff(dd, 0, getdate()) + 1, 0) as Tomorrow
          ,dateadd(wk, datediff(wk, 0, getdate()) + 1, 0) as NextWeekStart
          ,dateadd(mm, datediff(mm, 0, getdate()) + 1, 0) as NextMonthStart
          ,dateadd(qq, datediff(qq, 0, getdate()) + 1, 0) as NextQuarterStart
          ,dateadd(yy, datediff(yy, 0, getdate()) + 1, 0) as NextYearStart
          ,dateadd(ms, -3, dateadd(dd, datediff(dd, 0, getdate()) + 1, 0)) as TodayEnd
          ,dateadd(ms, -3, dateadd(wk, datediff(wk, 0, getdate()) + 1, 0)) as ThisWeekEnd
          ,dateadd(ms, -3, dateadd(mm, datediff(mm, 0, getdate()) + 1, 0)) as ThisMonthEnd
          ,dateadd(ms, -3, dateadd(qq, datediff(qq, 0, getdate()) + 1, 0)) as ThisQuarterEnd
          ,dateadd(ms, -3, dateadd(yy, datediff(yy, 0, getdate()) + 1, 0)) as ThisYearEnd
    

    使用上面的列表可以确定任何类型的范围。

    【讨论】:

    • “SQL Server DATETIME 列的分辨率最多为 3 毫秒”是一个鲜为人知的事实。我以前只听说过一次提到这个宝石。非常详细。
    【解决方案2】:

    以下内容将为您找到上个月的开始:

    -- Start of last month 
    SELECT CAST('01 '+ RIGHT(CONVERT(CHAR(11),DATEADD(MONTH,-1,GETDATE()),113),8) AS datetime)
    

    然后你会找到这个月的开始,使用下面的减一。

    -- Start of the month 
    SELECT CAST('01 '+ RIGHT(CONVERT(CHAR(11),GETDATE(),113),8) AS datetime) 
    

    当我必须在 SQL Server 中处理日期时,我经常引用 Robyn Page's SQL Server DATE/TIME Workbench。工作台(教程)布局合理,包含了我在 SQL Server 上处理日期时所需要的几乎所有内容。

    【讨论】:

      【解决方案3】:

      这个怎么样?

      select DATEADD(month, -1, GETDATE())
      

      【讨论】:

      • 好极了。 +1 最短查询
      【解决方案4】:

      我建议使用上个月的第一天和当月的第一天进行操作,而不是使用 >= 和

      这是 sql。你会注意到我已经包含了上个月的最后一天的值,以防你最终采用另一种方法。

      请注意,这些日期是从当天凌晨 12:00 开始计算的。换句话说,获取 介于 2009 年 6 月 1 日和 2009 年 6 月 30 日之间的值不会得到你想要的,因为 2009 年 6 月 30 日的所有时间都被排除在外。如果您使用 7 月的第一天(2009 年 7 月 1 日),您将获得保障。

      再次,我建议避免 BETWEEN 一起使用,如下所示。祝你好运。

      Declare @LastMonthFirstDay datetime
      Declare @LastMonthLastDay datetime
      Declare @ThisMonthFirstDay datetime
      
      Set @LastMonthFirstDay =  DATEADD(MONTH, DATEDIFF(MONTH, 0, CURRENT_TIMESTAMP) - 1, 0);
      Set @ThisMonthFirstDay = DATEADD(MONTH, DATEDIFF(MONTH, 0, CURRENT_TIMESTAMP), 0);
      Set @LastMonthLastDay = DATEADD(DAY, -1, DATEADD(MONTH, DATEDIFF(MONTH, 0, CURRENT_TIMESTAMP), 0));
      
      Select * From Table
      Where DateEntered >= @LastMonthFirstDay 
      And DateEntered < @ThisMonthFirstDay;
      

      【讨论】:

      • 我认为您将边界日期分配给变量的方法肯定更易于维护。但是,我的印象是 BETWEEN 的性能优于 >=
      • @ahsteele - 你可能是对的。正如你所提到的,“约会是一种愉快的工作。”我发现在过滤日期时,我需要多次更改我的查询,然后才能让它们尽可能地发挥最佳性能。我发现 >= with
      【解决方案5】:

      尝试使用 DATEADD 函数。您可以在 MONTH (mm) 日期部分中添加 -1,它应该可以工作。 Here is a link

      【讨论】:

        【解决方案6】:
        where year(S.DATEENTERED) = year(dateadd(mm, -1, getdate())) and month(S.DATEENTERED) = month(dateadd(mm, -1, getdate()))
        

        在性能方面可能不是很好,但你已经明白了。

        【讨论】:

          【解决方案7】:

          获取上个月的第一天

          SELECT DATEADD(MM, DATEDIFF(MM, '01/01/2000', DATEADD(MM, -1,GETDATE())), '01/01/2000')
          

          获取上个月的最后一天

          SELECT DATEADD(SS,-1,DATEADD(MM, DATEDIFF(MM,'01/01/2000',GETDATE()),'01/01/2000')) 
          

          然后根据这个范围搜索。

          【讨论】:

            【解决方案8】:

            试试:

            declare @lastm int
            set @lastm = datepart(mm,getdate()) - 1
            

            ...

            where datepart(mm,s.dateentered) = @lastm
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2019-01-03
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多