按月分解日期范围

时间:2011-06-07 18:27:09

标签: sql sybase

我有一系列数据,其开始日期和结束日期通常是从月初到该月末。但有时也有行 - 几个月了 - 从一个月中开始,在同一个月或未来一个月结束 - 从一个月的开始开始,但在未来一个月中的某个地方结束。

我需要按月打破这些日期范围,但不知道如何解决这个问题。

任何指导都表示赞赏。

感谢,

2 个答案:

答案 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语句,这样您就可以获取当月的开始日期,即开始日期和月初的最大值,以及月份的结束日期,即提供的结束和月末的最小值。

这样您就可以使用单个日期范围并获取一组月份日期范围。然后,您可以将该查询加入到当月的数据集和分组中,以便将您的数据按月分为几个月。 (当某些时间段可能没有数据但是您希望它们显示时,此技巧特别有用。只需使用左连接。)