显示给定开始日期和结束日期的天数

时间:2014-04-14 20:51:16

标签: sql sql-server ssms

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

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

结果如下:

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

3 个答案:

答案 0 :(得分:2)

SQL在“创建”数据方面并不出色 - 这意味着如果您需要获取两个日期之间的日期(或月份)列表,那么SQL必须循环并一次创建一行数据。

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

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

假设你有这样一个表,那么查询就是:

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

答案 1 :(得分:0)

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

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

答案 2 :(得分:0)

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)