SQL Server pt2

时间:2015-12-29 15:47:45

标签: sql-server date-range

这个问题与这篇文章有关:Split date range into one row per month in sql server

但我是Stackoverflow的新手,不允许新用户对提供的解决方案发表评论。这就是我现在将其添加为新问题的原因。

问题是:

  

我有一个包含两列的表,名为" from_date"和" to_date"

     

表格如下:

     

Table (I am not allowed to embed my picture here, so please click the link)

     

我想要的结果如下: -

     

from_date || TO_DATE
  ----------- ------------

     

2013-11-25 || 2013年11月30日

     

2013-12-01 || 2013年12月5日

     

该日期从2013-11-25分为2013-11-30,另一个日期从2013-12-01分到2013-12-05 ......是否有可能像这样分开?

Aaron Bertrand的解决方案就是:

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(MONTH, n.n+1, DATEADD(DAY, 0-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;

结果:

original_from_date   original_to_date   new_from_date   new_to_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

Aaron Bertrand的答案是一个超级强大的查询,但它似乎只有在一个月的31个月之后的一个月内才有效。如果您将startdate更改为,例如,2013-5-25(仅在4月之后,仅30天),则new_to_date值不正确:所有完整月份突然最多30天,然后:

original_from_date  original_to_date    new_from_date   new_to_date
2013-05-25          2013-12-05          2013-05-25      2013-05-30
2013-05-25          2013-12-05          2013-06-01      2013-06-30
2013-05-25          2013-12-05          2013-07-01      2013-07-30
2013-05-25          2013-12-05          2013-08-01      2013-08-30
2013-05-25          2013-12-05          2013-09-01      2013-09-30
2013-05-25          2013-12-05          2013-10-01      2013-10-30
2013-05-25          2013-12-05          2013-11-01      2013-11-30
2013-05-25          2013-12-05          2013-12-01      2013-12-05

任何人都可以编辑查询,以便结束日期是正确的(28,30,31天和29个月的飞跃),无论开始日期在哪个月?我无法弄清楚如何去做。

非常感谢,Martijn Vermunt

1 个答案:

答案 0 :(得分:0)

已经提供了答案,查询已被编辑并完善。谢谢@Aaron Bertrand 用于更新查询!

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;