我正在尝试编写一个T-SQL查询,该查询将列出给定开始日期和结束日期的天数。例如:
结果如下:
Jan 2014 | Feb 2014 | March 2014
----------------------------------
15 | 28 | 15
答案 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)