【问题标题】:SQL Get the first occurance of the 15th for a dateSQL 获取日期第一次出现的第 15 次
【发布时间】:2011-05-13 14:25:50
【问题描述】:

我需要编写一个函数或 SP 来返回第 15 次的第一次出现。例如,如果我将日期设置为 5 月 8 日,那么它应该返回 5 月 15 日。如果我过了 5 月 30 日,那么它应该会在 6 月 15 日返回。

【问题讨论】:

  • 你试一试了吗?你有尝试过的代码吗?
  • 这个函数会一直传递当前日期,还是可以随时传递任意日期?
  • +1 @YAU 我同意,SO 似乎正在成为“为我做我的工作”的资源,而不是帮助解决棘手问题的地方。很难知道在哪里划线,但我认为通过阅读 MSSQL 日期函数 (msdn.microsoft.com/en-us/library/ms186724%28v=SQL.100%29.aspx) 和控制逻辑 (msdn.microsoft.com/en-us/library/ms174290.aspx) 文档可以轻松解决这个问题。我知道 OP 可能会从下面提供的答案中学到一些东西,但如果没有,那将是令人沮丧的。

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


【解决方案1】:

一种方式

   DECLARE @d DATETIME
    SELECT @d = '20110508'
    --SELECT @d = '20110530'


    SELECT  CASE WHEN DAY(@d)  > 15 
    THEN  dateadd(mm, datediff(mm, 0, @d)+1, 0) + 14
    ELSE dateadd(mm, datediff(mm, 0, @d)+0, 0)+ 14 end

【讨论】:

  • 如果你将getdate() 更改为@d 我想你会得到它。它现在仅在您使用 5-15 天(或今天的正确结果)时才有效。
  • 在您的第一个示例中:SELECT CASE WHEN DAY(@d) > 15 THEN dateadd(mm, datediff(mm, 0, getdate())+1, 0) + 14 ELSE dateadd(mm, datediff(mm, 0, getdate())+0, 0)+ 14 end 这是错误的。用'20110710'试试,你会得到5-15。显然这是错误的。因为第一个示例中的getdate() 必须是@d。 OP 没有表明您认为他们将始终超过当前日期。
  • 在进行 datediff 之前从 @d 中减去 15 天,而不是 CASE WHEN THEN?
【解决方案2】:

怎么样;

create function udf_getNextDate(@base datetime, @day int) returns datetime as begin
    set @base = case when day(@base) > @day         
            then dateadd(month, 1, @base)
        else @base
    end
    return dateadd(day, -day(@base) + @day, @base)
end

select 
  dbo.udf_getNextDate('08 may 2011', 15),
  dbo.udf_getNextDate('30 may 2011', 15),
  dbo.udf_getNextDate('16 dec 2011', 15),
  dbo.udf_getNextDate('01 may 2011', 15)

2011-05-15 00:00:00.000 
2011-06-15 00:00:00.000 
2012-01-15 00:00:00.000 
2011-05-15 00:00:00.000

【讨论】:

    【解决方案3】:

    只是另一种方式:

    Declare @d datetime
    
    Set @d = getdate()
    
    
    Select  Case 
                When    DateDiff(Day, Day(@d), 15) < 0 then 
                        DateAdd(month, 1, DateAdd(Day, DateDiff(Day, Day(@d), 15), @d))
                Else    DateAdd(Day, DateDiff(Day, Day(@d), 15), @d) 
            End as [Next15th]
    

    【讨论】:

      【解决方案4】:

      这个功能可以帮到你

      create function Get15th(@date datetime)
      returns datetime 
      as
      begin
      declare @resultdate datetime
      declare @y int
      declare @m int
      declare @d int
      set @y = datepart(year,@date)
      set @m = datepart(month,@date)
      set @d = datepart(day,@date)
      if( @d<=15)
      set @resultdate =cast((str(@y)+'-'+str(@m)+'-15') as datetime)
      else
      set @resultdate =cast((str(@y)+'-'+str(@m+1)+'-15') as datetime)
      return  @resultdate 
      end
      

      【讨论】:

        【解决方案5】:

        试试

        DATEADD(Day, DATEDIFF(Day, 15, Created), 0) AS CreatedDay 
        

        在这里解释http://improve.dk/archive/2006/12/13/sql-server-datetime-rounding-made-easy.aspx

        使用该链接,你可以实现你想要的

        更新:弄错了……见德姆斯回答

        【讨论】:

        • 你能插上20110508我回来2011-04-23 00:00:00.000
        • DateDiff 需要区分月份,而不是日期。您的代码将 Created 向下舍入到最近的一天,然后减去 15 天...
        • @mellamokb - 抱歉,我无法对此进行测试,但确实提供了一个链接供用户尝试自己解决。
        【解决方案6】:

        Rob 的回答很接近……

        如果您以月而不是天为单位计算 datediff,并将您的基数设为一个月的 15 号,那么就多加一个月...

        DATEADD(MONTH, DATEDIFF(MONTH, 14, Created) + 1, 14)

        编辑

        修改为使用 DATEDIFF MONTH 它是如何工作的,而不是我认为它应该如何工作 ;)

        DATEADD(MONTH, DATEDIFF(MONTH, 0, Created - 15) + 1, 14)

        【讨论】:

        • 不完全:5-1 -> 6-15,不是下一次发生。 5-1 应该返回 5-15。您需要像 @SQLMenace 这样的额外检查来处理 15 日之前和 15 日之后的情况。
        • 我的错误,应该测试一下。将创建日期偏移 -15 天,以避免使用 CASE WHEN THEN。
        【解决方案7】:

        我通常会这样做:

        declare
          @date       datetime ,
          @target_day int
        
        set @date       = 'June 16, 2009'
        set @target_day = 15
        
        select date      = @date ,
               next_date = case when day(@date) <= @target_day
                             then dateadd(day,15-day(@date),@date)
                             else dateadd(day,15,dateadd(month,1,dateadd(day,-day(@date),@date)))
                           end
        

        处理每月的最后一天有点棘手,因为月份的天数是可变的,而且 SQL Server 的日期数学有时有点巴洛克式。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-08-27
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多