Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/81.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在sql server中每月将日期范围拆分为一行_Sql_Sql Server - Fatal编程技术网

在sql server中每月将日期范围拆分为一行

在sql server中每月将日期范围拆分为一行,sql,sql-server,Sql,Sql Server,我有一个表,有两列,分别是from_date和to_date the table look like:- 我想要的结果是:- from_date to_date ----------- ------------ 2013-11-25 2013-11-30 2013-12-01 2013-12-05 该日期从2013年11月25日分为2013年11月30日,另一日期从2013年12月01日分为201

我有一个表,有两列,分别是from_date和to_date

    the table look like:-
我想要的结果是:-

from_date            to_date   
-----------         ------------  
2013-11-25           2013-11-30
2013-12-01           2013-12-05

该日期从2013年11月25日分为2013年11月30日,另一日期从2013年12月01日分为2013年12月05日。。。可以这样拆分吗?

这是闰年安全的,可以处理日期范围,而其他答案目前没有

DECLARE @d TABLE(from_date DATE, to_date DATE);

INSERT @d VALUES ('2013-11-25','2013-12-05');

;WITH n(n) AS 
(
  SELECT ROW_NUMBER() OVER (ORDER BY [object_id])-1 FROM sys.all_columns
),
d(n,f,t,md,bp,ep) AS 
(
  SELECT n.n, d.from_date, d.to_date, 
    DATEDIFF(MONTH, d.from_date, d.to_date),
    DATEADD(MONTH, n.n, DATEADD(DAY, 1-DAY(from_date), from_date)),
    DATEADD(DAY, -1, DATEADD(MONTH, 1, DATEADD(MONTH, n.n, 
      DATEADD(DAY, 1-DAY(from_date), from_date))))
 FROM n INNER JOIN @d AS d 
 ON d.to_date >= DATEADD(MONTH, n.n-1, d.from_date)
)
SELECT original_from_date = f, original_to_date = t, 
  new_from_date = CASE n WHEN 0  THEN f ELSE bp END,
  new_to_date   = CASE n WHEN md THEN t ELSE ep END 
FROM d WHERE md >= n
ORDER BY original_from_date, new_from_date;
结果:

原始日期原始日期到新日期从新日期到新日期 --------- -------- ------- ------ 2013-11-25 2013-12-05 2013-11-25 2013-11-30 2013-11-25 2013-12-05 2013-12-01 2013-12-05
如果您在维度数据仓库中操作,请使用日期维度。否则,请使用CTE

WITH cte AS
(SELECT from_date
      , to_date
      , from_date AS mo_from_date
      , DATEADD(day, day(from_date)* -1 + 1, from_date) AS bom_date
   FROM DateTable
UNION ALL
SELECT from_date
     , to_date
     , DATEADD(month,1,bom_date)
     , DATEADD(month,1,bom_date)
  FROM cte
 where DATEADD(month,1,mo_from_date) < to_date
)
SELECT mo_from_date
     , CASE when to_date < DATEADD(month,1,bom_date) THEN
           to_date
       ELSE
           DATEADD(day, -1, DATEADD(month,1,bom_date))
       END AS mo_to_date
  FROM cte

以下几点几乎相同。它只适用于整月,但修改它以适用于部分月份也应该很简单:如果日期跨度为3个月,例如2013-11-25到2014-02-05,那么这应该分为3行还是4行?如果第一个起始日期适用于少于31天的月份之后的月份,则您的解决方案无法正确找到该月份的最后一天。从十月开始,而不是十一月。十月紧接着九月,九月只有不到31天。我没有找到这个。马蒂恩·维蒙特做到了@奥伦伯特朗,你,先生,洛克!如果我有时间约会呢?当我用日期定义了时间时,我尝试了上面的查询,但是将时间分割成月份是错误的