Я работал над примером ранее и в итоге не опубликовал его, но вернулся и решил опубликовать его в любом случае:)
-- Sample Data
CREATE TABLE #SampleVals ( ID int, Open_Date Date, Close_Date Date);
INSERT INTO #SampleVals(ID, Open_Date, Close_Date)
VALUES(1,'20100101','20100301'),
(2,'20110121','20110212'),
(3,'20100301', NULL),
(4,'20100110',NULL);
-- Get Start/End for full date range
DECLARE @Min Date, @Max Date;
SELECT @Min = DateAdd(dd,-1 * Day(MIN(Open_Date)) + 1, MIN(Open_Date)),
@Max = MAX(Close_Date)
FROM #SampleVals;
-- Query for values across entire range
WITH DateRange (StartDate,NextDate) AS (
SELECT DATEADD(MONTH, n-1, @Min),
DATEADD(MONTH, n, @Min)
FROM dbo.Number N
WHERE N.n <= DATEDIFF(MONTH,@Min,@Max) + 1
)
SELECT MONTH(DR.StartDate),
YEAR(DR.StartDate),
SUM(CASE WHEN S.Open_Date >= DR.StartDate Then 1 Else 0 END) AS [Open],
SUM(CASE WHEN S.Close_Date < DR.NextDate Then 1 Else 0 END) AS [Closed]
FROM DateRange DR
LEFT JOIN #SampleVals S ON S.Open_Date < DR.NextDate
AND (S.Close_Date >= DR.StartDate OR S.Close_Date IS NULL)
GROUP BY DR.StartDate
ORDER BY DR.StartDate;
-- Cleanup sample data
DROP TABLE #SampleVals;
Даты для образцов данных были изменены, чтобы отразить ггггммдд.Я также использовал локальную таблицу чисел:
CREATE TABLE dbo.Number(n INT NOT NULL IDENTITY) ;
GO
SET NOCOUNT ON ;
INSERT dbo.Number DEFAULT VALUES ;
WHILE SCOPE_IDENTITY() < 5000
INSERT dbo.Number DEFAULT VALUES ;
Я почти не публиковал это, поскольку Norla сделал это раньше, чем закончил, но я заметил, что решение Norla заполняет столбец Close, если дата началабыл закрыт (и для месяца с этой начальной датой), в то время как эта версия заполняет столбец месяца закрытия с месяцем close_date, который, как я полагаю, является тем, о чем вы просили.