我有一系列数据,其开始日期和结束日期通常是从月初到该月末。但有时也有行 - 几个月了 - 从一个月中开始,在同一个月或未来一个月结束 - 从一个月的开始开始,但在未来一个月中的某个地方结束。
我需要按月打破这些日期范围,但不知道如何解决这个问题。
任何指导都表示赞赏。
感谢,
答案 0 :(得分:2)
您可以使用数字表执行此任务。
在下面的示例查询中,名为master..spt_values
的系统表用作数字表的替代:
SELECT
CASE WHEN BeginDate > MonthStart THEN BeginDate ELSE MonthStart END AS BeginDate,
CASE WHEN EndDate < MonthEnd THEN EndDate ELSE MonthEnd END AS EndDate,
… /* other columns as needed */
FROM (
SELECT
d.*, /* or you could be more specific here */
(
DATEADD(month, DATEDIFF(month, 0, d.BeginDate) + v.number, 0)
) AS MonthStart,
DATEADD(day, -1,
DATEADD(month, DATEDIFF(month, 0, d.BeginDate) + v.number + 1, 0)
) AS MonthEnd
FROM RowsOfData d
INNER JOIN master..spt_values v ON v.type = 'P'
AND v.number BETWEEN 0 AND DATEDIFF(month, d.BeginDate, d.EndDate)
) s
每一行都分为一系列行,其中BeginDate
是实际BeginDate
或月初,具体取决于更高的值,EndDate
也是如此。为了说明,以下行
BeginDate EndDate
---------- ----------
2010-03-05 2010-03-24
2010-04-16 2010-05-05
2010-06-29 2006-08-12
2010-10-10 2011-02-01
会像这样分开:
BeginDate EndDate
---------- ----------
2010-03-05 2010-03-24
2010-04-16 2010-04-30
2010-05-01 2010-05-05
2010-06-29 2010-06-30
2010-07-01 2010-07-31
2010-08-01 2010-08-12
2010-10-10 2010-10-31
2010-11-01 2010-11-30
2010-12-01 2010-12-31
2011-01-01 2011-01-31
2011-02-01 2011-02-02
答案 1 :(得分:1)
一个标准技巧是创建一个months
表,然后选择与日期范围相交的所有月份。
您可以更进一步,在您的选择中使用CASE
语句,这样您就可以获取当月的开始日期,即开始日期和月初的最大值,以及月份的结束日期,即提供的结束和月末的最小值。
这样您就可以使用单个日期范围并获取一组月份日期范围。然后,您可以将该查询加入到当月的数据集和分组中,以便将您的数据按月分为几个月。 (当某些时间段可能没有数据但是您希望它们显示时,此技巧特别有用。只需使用左连接。)