Skip to main content
Slightly more compact version.
Source Link
Aaron Bertrand
  • 181.5k
  • 28
  • 402
  • 619

Here's my attempt. Still think there are unanswered questions in your sample data, though.

DECLARE @s SMALLDATETIME, @e SMALLDATETIME;
SELECT  @s = '20120302',  @e = '20120605';

WITH;WITH n(n) AS
(
  SELECT TOP (DATEDIFF(MONTH, @s, @e)+1) ROW_NUMBER() OVER 
  (ORDER BY [object_id])-1 FROM sys.all_objects
),
m(m) AS ( SELECT DATEADD(DAY, 1-DAY(@s), @s) ),
x(n,s,e,fd,ld) AS 
(
  SELECT n.n, @s, @e, DATEADD(MONTH, n.n, m.m), DATEADD(MONTH, n.n+1, m.m)
  FROM n, CROSS(SELECT JOINDATEADD(DAY, 1-DAY(@s), @s)) AS m(m)
)
SELECT [Month] = DATENAME(MONTH, fd), [Days] = DATEDIFF(DAY, fd, ld) 
  - CASE WHEN s@s > fd THEN (DATEDIFF(DAY, fd, s@s)+1) ELSE 0 END
  - CASE WHEN e@e < ld THEN (DATEDIFF(DAY, e@e, ld)-1) ELSE 0 END
  FROM x;

Results:

Month  Days
-----  ----
March    29
April    30
May      31
June      5

Here's my attempt. Still think there are unanswered questions in your sample data, though.

DECLARE @s SMALLDATETIME, @e SMALLDATETIME;
SELECT  @s = '20120302',  @e = '20120605';

WITH n(n) AS
(
  SELECT TOP (DATEDIFF(MONTH, @s, @e)+1) ROW_NUMBER() OVER 
  (ORDER BY [object_id])-1 FROM sys.all_objects
),
m(m) AS ( SELECT DATEADD(DAY, 1-DAY(@s), @s) ),
x(n,s,e,fd,ld) AS 
(
  SELECT n.n, @s, @e, DATEADD(MONTH, n.n, m.m), DATEADD(MONTH, n.n+1, m.m)
  FROM n CROSS JOIN m
)
SELECT DATENAME(MONTH, fd),DATEDIFF(DAY, fd, ld) 
  - CASE WHEN s > fd THEN (DATEDIFF(DAY, fd, s)+1) ELSE 0 END
  - CASE WHEN e < ld THEN (DATEDIFF(DAY, e, ld)-1) ELSE 0 END
  FROM x;

Results

-----  --
March  29
April  30
May    31
June    5

Here's my attempt. Still think there are unanswered questions in your sample data, though.

DECLARE @s SMALLDATETIME, @e SMALLDATETIME;
SELECT  @s = '20120302',  @e = '20120605';

;WITH n(n) AS
(
  SELECT TOP (DATEDIFF(MONTH, @s, @e)+1) ROW_NUMBER() OVER 
  (ORDER BY [object_id])-1 FROM sys.all_objects
),
x(n,fd,ld) AS 
(
  SELECT n.n, DATEADD(MONTH, n.n, m.m), DATEADD(MONTH, n.n+1, m.m)
  FROM n, (SELECT DATEADD(DAY, 1-DAY(@s), @s)) AS m(m)
)
SELECT [Month] = DATENAME(MONTH, fd), [Days] = DATEDIFF(DAY, fd, ld) 
  - CASE WHEN @s > fd THEN (DATEDIFF(DAY, fd, @s)+1) ELSE 0 END
  - CASE WHEN @e < ld THEN (DATEDIFF(DAY, @e, ld)-1) ELSE 0 END
  FROM x;

Results:

Month  Days
-----  ----
March    29
April    30
May      31
June      5
Source Link
Aaron Bertrand
  • 181.5k
  • 28
  • 402
  • 619

Here's my attempt. Still think there are unanswered questions in your sample data, though.

DECLARE @s SMALLDATETIME, @e SMALLDATETIME;
SELECT  @s = '20120302',  @e = '20120605';

WITH n(n) AS
(
  SELECT TOP (DATEDIFF(MONTH, @s, @e)+1) ROW_NUMBER() OVER 
  (ORDER BY [object_id])-1 FROM sys.all_objects
),
m(m) AS ( SELECT DATEADD(DAY, 1-DAY(@s), @s) ),
x(n,s,e,fd,ld) AS 
(
  SELECT n.n, @s, @e, DATEADD(MONTH, n.n, m.m), DATEADD(MONTH, n.n+1, m.m)
  FROM n CROSS JOIN m
)
SELECT DATENAME(MONTH, fd),DATEDIFF(DAY, fd, ld) 
  - CASE WHEN s > fd THEN (DATEDIFF(DAY, fd, s)+1) ELSE 0 END
  - CASE WHEN e < ld THEN (DATEDIFF(DAY, e, ld)-1) ELSE 0 END
  FROM x;

Results

-----  --
March  29
April  30
May    31
June    5