【问题标题】:Show number of days given a start and end date显示给定开始和结束日期的天数
【发布时间】:2014-04-16 16:47:25
【问题描述】:

我正在尝试编写一个 T-SQL 查询,该查询将列出给定开始日期和结束日期的天数。例如:

  • 开始日期 - 2014 年 1 月 15 日
  • 结束日期 - 2014 年 3 月 15 日

结果如下所示:

Jan 2014 | Feb 2014 | March 2014
---------------------------------- 
  15     |    28    |     15

【问题讨论】:

  • 好的,那么您编写了哪些 T-SQL 来尝试完成此任务?请根据您的尝试编辑您的问题。
  • 澄清一下:在你的结果中,一月的数字不应该是 16,因为一个月有 31 天? (假设您从开始日期算起当月剩余的天数)
  • 你已经有日历表了吗?

标签: sql sql-server ssms


【解决方案1】:

SQL 不擅长“创建”数据——这意味着如果您需要获取两个日期之间的日期(或月份)列表,那么 SQL 本质上必须循环并一次创建一行数据。

如果这是一种常见模式,您将受益于创建一个物理表,该表将每个日期存储为一行以及有关该日期的各种元数据(月、年、工作日、一年中的一周等)——否则称为日历表

(您也可以使用 CTE 或其他机制制造一个,但使用物理表可能会快得多)

假设您有这样一个表,查询将是:

SELECT Month,COUNT(*)
FROM Dates
WHERE Date BETWEEN @StartDate and @EndDate

【讨论】:

    【解决方案2】:

    请参阅我上面关于计算第一个月的天数的评论。我假设您要返回从开始日期开始的月份中剩余的天数。这是一个使用测试日期完成此操作的循环:

    DECLARE @BeginDate    DATE = '1/15/2014',
            @EndDate      DATE = '3/15/2015',
            @CurrentMonth INT = 0
    
    DECLARE @MonthCounter INT = DATEDIFF(Month, @BeginDate, @EndDate) + 1
    DECLARE @Results TABLE (DateValue DATE, NumberOfDays INT)
    
    WHILE @CurrentMonth < @MonthCounter
    BEGIN
    
        IF @CurrentMonth = 0
            BEGIN
                INSERT @Results
                SELECT DATEADD(MONTH,@CurrentMonth,@BeginDate) AS DateValue,
                    DAY(EOMONTH(DATEADD(MONTH,@CurrentMonth,@BeginDate))) - DAY(@BeginDate) AS NumberOfDays
            END
        ELSE IF @CurrentMonth = @MonthCounter - 1
            BEGIN
                INSERT @Results
                SELECT DATEADD(MONTH,@CurrentMonth,@BeginDate) AS DateValue,
                    DAY(@EndDate) AS NumberOfDays
            END
        ELSE
            BEGIN
                INSERT @Results
                SELECT DATEADD(MONTH,@CurrentMonth,@BeginDate) AS DateValue,
                    DAY(EOMONTH(DATEADD(MONTH,@CurrentMonth,@BeginDate))) AS NumberOfDays
            END
    
        SET @CurrentMonth = @CurrentMonth + 1
    
    END
    
    SELECT DATENAME(Month,DateValue) + ' ' + CONVERT(VARCHAR(10),YEAR(DateValue)) AS [Month], NumberOfDays
    FROM @Results
    

    【讨论】:

      【解决方案3】:
      DECLARE @StartDate AS datetime = '20140115';
      DECLARE @EndDate AS datetime = '20140315';
      
      WITH DatesBetweenStartAndEnd AS (
          SELECT @StartDate AS [Date]
        UNION ALL
          SELECT DATEADD(day, 1, [Date])
          FROM DatesBetweenStartAndEnd
          WHERE [Date] < @EndDate
      )
      SELECT DATENAME(month, [YearMonth]) + ' ' + DATENAME(year, [YearMonth])
            ,COUNT(*)
      FROM DatesBetweenStartAndEnd
           CROSS APPLY (
              SELECT DATEADD(day, 1-DAY([Date]), [Date]) AS [YearMonth] 
           ) AS CA1
      GROUP BY [YearMonth]
      OPTION (MAXRECURSION 0)
      

      【讨论】:

        猜你喜欢
        • 2012-04-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多