【问题标题】:Datetime values generation MS SQL日期时间值生成 MS SQL
【发布时间】:2020-11-06 14:59:20
【问题描述】:

有两个可用的 DateTime 值变量:例如,@STARTDATETIME = '2020-10-21 14:45' 和 @ENDDATETIME = '2020-10-22 19:00'

如果 STARTDATETIME = '2020-10-21 12:00' 和 ENDDATETIME = '2020-10-21 16:00' 这样的日期之间只有一天,则变量必须保存初始值。

如果两个值之间有一天或多天,则第一个日期必须从给定的时间戳开始到 16:00。所有中间天的时间必须是从 08:00 到 16:00。最后一天必须从 08:00 时间开始,直到给定的时间戳。

完整示例:

@STARTDATETIME = '2020-10-21 14:45' and @ENDDATETIME = '2020-10-23 19:15'

期望的输出(表格):

STARTDATETIME      | ENDDATETIME 
'2020-10-21 14:45' | '2020-10-21 16:00'
'2020-10-22 08:00' | '2020-10-22 16:00'
'2020-10-23 08:00' | '2020-10-23 19:15'

【问题讨论】:

    标签: sql sql-server datetime range


    【解决方案1】:

    您可以使用递归 CTE:

    with dates as (
          select @STARTDATETIME as startdt,
                 (case when datediff(day, @STARTDATETIME, @ENDDATETIME) = 0
                       then @ENDDATETIME
                       else dateadd(day, 1, convert(date, @STARTDATETIME))
                  end) as enddt
          union all
          select enddte,
                 (case when datediff(day, enddte, @ENDDATETIME) = 0
                       then @ENDDATETIME
                       else dateadd(day, 1, convert(date, enddte))
                  end) as enddt,
                 @ENDDATETIME as enddatetime
          from dates
          where enddt < @enddatetime
         )
    select *
    from date;
    

    【讨论】:

      【解决方案2】:

      这个会每天给你一排:

      
          DECLARE @start dateTime = '20201021 14:45:00'
          DECLARE @end dateTime = '20201023 19:15:00'
          DECLARE @startDate Date = CAST(@start as date)
          DECLARE @endDate Date = CAST(@end as date)
          DECLARE @startTime Time = CAST(@start as time)
          DECLARE @endTime Time = CAST(@end as time)
          DECLARE @startOfDay DateTime = '08:00:00'
          DECLARE @endOfDay DateTime = '16:00:00';
          
          
          WITH lv0 AS (SELECT 0 g UNION ALL SELECT 0)
              ,lv1 AS (SELECT 0 g FROM lv0 a CROSS JOIN lv0 b) -- 4
              ,lv2 AS (SELECT 0 g FROM lv1 a CROSS JOIN lv1 b) -- 16
              ,lv3 AS (SELECT 0 g FROM lv2 a CROSS JOIN lv2 b) -- 256
              ,lv4 AS (SELECT 0 g FROM lv3 a CROSS JOIN lv3 b) -- 65,536
              ,lv5 AS (SELECT 0 g FROM lv4 a CROSS JOIN lv4 b) -- 4,294,967,296
              ,Tally (n) AS (SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) FROM lv5)
          ,
          dates AS
          (
          SELECT 
            DateAdd(day,n-1,@startDate) as [Day]
          FROM tally
          WHERE n<=DATEDIFF(day,@startDate,@endDate)+1
          )
          select 
            [Day],
            CASE WHEN [Day]=@startDate THEN @start ELSE CAST([DAY] AS DateTime)+@startOfDay END as [startOfWork],
            CASE WHEN [Day]=@endDate THEN @end ELSE CAST([DAY] AS DateTime)+@endOfDay END as [endOfWork]
          
          FROM dates
      

      结果:

      | Day        | startOfWork             | endOfWork               |
      |------------|-------------------------|-------------------------|
      | 2020-10-21 | 2020-10-21 14:45:00.000 | 2020-10-21 16:00:00.000 |
      | 2020-10-22 | 2020-10-22 08:00:00.000 | 2020-10-22 16:00:00.000 |
      | 2020-10-23 | 2020-10-23 08:00:00.000 | 2020-10-23 19:15:00.000 |
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-02-21
        • 1970-01-01
        • 2010-12-06
        • 2012-08-21
        • 2021-02-28
        • 1970-01-01
        相关资源
        最近更新 更多