【问题标题】:SQL Server 2012: Round to NEAREST(!) start of month (in timestamp format) from a timestamp column)SQL Server 2012:从时间戳列舍入到 NEAREST(!) 月初(时间戳格式)
【发布时间】:2012-12-02 00:52:24
【问题描述】:

我需要从时间戳列四舍五入到最近的月初(时间戳格式)。

如何做到这一点?

例子:

TimestampColumn A:             Rounded to these values
2012-01-07 18:18:29.923        2012-01-01 00:00:00.000
2012-01-14 12:58:13.122        2012-01-01 00:00:00.000
2012-06-09 17:10:30.787        2012-06-01 00:00:00.000
2012-05-31 09:29:43.870        2012-06-01 00:00:00.000
2012-10-22 12:09:47.067        2012-11-01 00:00:00.000
2012-10-15 04:35:11.013        2012-10-01 00:00:00.000

【问题讨论】:

  • 您的研究/尝试在哪里?另外,您为什么要将时间戳列用于除时间戳之外的任何内容?
  • 研究/尝试:回合和几个演员的组合,但它不够好,无法在此处显示。时间戳:方便和熟悉的初学者。
  • 有总比没有好...

标签: tsql sql-server-2012


【解决方案1】:

考虑先转换为日期

DECLARE @d DATETIME
set @d = CONVERT(DATE, '2012-02-14 12:58:13.122')

SET @d =  DATEADD(DAY, 1-datepart(day, @d), @d)

SELECT @d

【讨论】:

    【解决方案2】:

    这是一种方法 - 只需减去您不关心的日期的所有部分:

    DECLARE @d DATETIME
    set @d = '2012-02-14 12:58:13.122'
    
    SET @d =  DATEADD(DAY, 1-datepart(day, @d), @d)
    SET @d =  DATEADD(hour, -datepart(hour, @d), @d)
    SET @d =  DATEADD(minute, -datepart(minute, @d), @d)
    SET @d =  DATEADD(second, -datepart(second, @d), @d)
    SET @d =  DATEADD(millisecond, -datepart(millisecond, @d), @d)
    
    SELECT @d
    

    【讨论】:

      【解决方案3】:

      以秒为单位计算适用月份的长度,然后确定您是否已过了月中。根据需要前进或后退。

      declare @Foo as DateTime = '2012-10-15 12:35:11.013'
      
      select
        DateAdd( month, DateDiff( m, 0, @Foo ), 0 ) as 'Year/Month',
        DateDiff( s, DateAdd( month, DateDiff( m, 0, @Foo ), 0), @Foo ) as 'Seconds Into Month',
        DateDiff( s, DateAdd( month, DateDiff( m, 0, @Foo ), 0 ), DateAdd( month, DateDiff( m, 0, @Foo ) + 1, 0 ) ) as 'Seconds In Month',
        DateDiff( s, DateAdd( month, DateDiff( m, 0, @Foo ), 0 ), DateAdd( month, DateDiff( m, 0, @Foo ) + 1, 0 ) ) / 2 as 'Seconds In Half Month',
        DateAdd( month, DateDiff( m, 0, @Foo ) + Round( 1.0 * DateDiff( s, DateAdd( month, DateDiff( m, 0, @Foo ), 0), @Foo ) / DateDiff( s, DateAdd( month, DateDiff( m, 0, @Foo ), 0 ), DateAdd( month, DateDiff( m, 0, @Foo ) + 1, 0 ) ), 0 ), 0 ) as 'Rounded Date'
      

      【讨论】:

        【解决方案4】:

        感谢您的贡献。但我会选择这个;它足够好。

        SELECT CASE
        WHEN DATEDIFF(DAY, GETDATE(), DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()) + 1, 0)) > 
        ABS(DATEDIFF(DAY, GETDATE(), DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()), 0))) 
        THEN DATEADD(dd, datediff(dd, 0, DATEADD(DAY, DATEDIFF(DAY, GETDATE(), DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()), 0)), GETDATE() ) )+0, 0)
        ELSE dateadd(dd, datediff(dd, 0, DATEADD(DAY, DATEDIFF(DAY, GETDATE(), DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()) + 1, 0)), GETDATE() ) )+0, 0)
        END
        

        【讨论】:

        • 您的问题并不清楚您是否想忽略一天中的时间。由于它包含在示例数据中,因此我假设您希望在 16 日中午正确拆分具有奇数天数的月份(奇数二月除外)。
        • 很抱歉。我想对你的贡献投赞成票,但由于 SO 的最低 15 个“点”规则,我不能投票......
        【解决方案5】:

        这是一个例子。您有 5 个字段:您要转换的日期、您想要的转换日期、当月的第一天、当月的最后一天和下个月的第一天。 只需选择您需要的内容:

        SELECT
            BED_Meeting_When,
            CASE WHEN DAY(BED_Meeting_When) < 15 THEN (DATEADD(DAY, (-DAY(BED_Meeting_When) + 1), BED_Meeting_When)) ELSE DATEADD(DAY, (-DAY(BED_Meeting_When) + 1), DATEADD(MONTH, 1, BED_Meeting_When)) END,
            DATEADD(DAY, (-DAY(BED_Meeting_When) + 1), BED_Meeting_When) AS 'Arrondi au premier du mois',
            DATEADD(DAY, -1, DATEADD(MONTH, DATEDIFF(MONTH, 0, BED_Meeting_When) + 1, 0)) AS 'Arrondi au dernier du mois',
            DATEADD(DAY, (-DAY(BED_Meeting_When) + 1), DATEADD(MONTH, 1, BED_Meeting_When)) AS 'Arrondi au premier du mois suivant',
            BEMR_Titre
        FROM bpri_entretien_detail
            INNER JOIN bpri_entretien_motif ON (BED_BEMR_Idx = BEMR_Idx)
        

        【讨论】:

          【解决方案6】:

          您好,我知道聚会迟到了,我希望一点简单的提议永远不会冒犯

          创建一个迷你临时表,我弹出了原始帖子中提供的日期

          然后从中选择如下

          创建表#DT(

          TS_A 日期时间,TS_B 日期时间)

          插入#DT (ts_a) 值('2012-01-07 18:18:29.923'), ('2012-01-14 12:58:13.122'), ('2012-06-09 17:10:30.787'), ('2012-05-31 09:29:43.870'), ('2012-10-22 12:09:47.067'), ('2012-10-15 04:35:11.013')

          从 #DT 中选择 TS_A, DATEADD(MONTH, DATEDIFF(MONTH, 0,ts_a), 0) TS_B

          结果 - 我希望这很清楚

          RESULTS

          令人惊讶的是它们的时代变化:-)

          TX
          我希望这结果没问题 十多年来没有在任何地方发布过

          【讨论】:

          • 正如目前所写,您的答案尚不清楚。请edit 添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。你可以找到更多关于如何写好答案的信息in the help center
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2017-08-29
          • 2016-06-27
          • 2017-05-29
          • 2015-12-14
          • 2020-09-05
          • 1970-01-01
          • 2011-06-03
          相关资源
          最近更新 更多