Setup, então temos certeza de que estamos falando da mesma coisa:
USE tempdb;
GO
CREATE TABLE dbo.users
(
[user_id] INT IDENTITY(1,1) PRIMARY KEY,
hired_date DATE NOT NULL,
termination_date DATE
);
CREATE TABLE dbo.[date table]
(
week_start DATE NOT NULL UNIQUE,
week_end AS CONVERT(DATE, DATEADD(DAY, 6, week_start))
);
GO
SET NOCOUNT ON;
GO
INSERT dbo.[date table](week_start) VALUES
('20110806'),
('20110813'),
('20110820');
INSERT dbo.users(hired_date, termination_date) VALUES
('20110101', NULL), -- long-time, active
('20110101', '20110807'), -- long-time, fired in week 1
('20110807', '20110815'), -- hired week 1, fired week 2
('20110816', '20110816'), -- hired week 2, fired week 2
('20110807', '20110825'), -- hired week 1, fired week 3
('20110806', NULL), -- hired week 1, active
('20110807', NULL), -- hired week 1, active
('20110813', NULL), -- hired week 2, active
('20110821', NULL); -- hired week 3, active
GO
Com essa lógica, deve haver 6 funcionários ativos durante a semana 1, 7 funcionários ativos durante a semana 2 e voltar para 6 novamente na semana 3. Levei alguns minutos desenhando as linhas ativas em um pedaço de papel para descobrir onde Errei na minha consulta. Agora vamos testar este com os dados de amostra que configuramos no tempdb:
;WITH last_8_weeks AS
(
SELECT TOP (8) week_start, week_end
FROM dbo.[date table]
WHERE week_start >= DATEADD(WEEK, -9, CURRENT_TIMESTAMP)
ORDER BY week_start DESC
)
SELECT d.week_end, COUNT(u.user_id)
FROM last_8_weeks AS d
LEFT OUTER JOIN dbo.users AS u
ON u.hired_date <= d.week_end
AND COALESCE(u.termination_date, DATEADD(DAY, 1, d.week_end)) >= d.week_start
GROUP BY d.week_end
ORDER BY d.week_end;
E depois limpe:
GO
DROP TABLE dbo.[date table], dbo.users;