Группировка всего активных пользователей за каждую из предыдущих 8 недель - PullRequest
2 голосов
/ 22 августа 2011

Мне нужно создать отчет следующим образом:

week-ending date    |   number of active users
8/6/2011                78
8/13/2011               98
8/20/2011               79

У меня есть таблица пользователей с этими полями

  • user_id
  • hired_date
  • termination_date
  • is_active

У меня также есть таблица дат за предыдущие 8 недель, к которой я планирую присоединиться ..

  • Начало_неделя
  • week_end
  • WEEK_NUM

Я застрял в том, как я могу получить активных пользователей. Как бы я сгруппировал их, потому что я пытался что-то с datepart, и это дало количество новых пользователей в течение недели (например, 4 пользователя, нанятых в неделю7), а это не то, что мне нужно. Я мог бы использовать некоторые указания здесь. Заранее спасибо.

SQL Server 2008

Ответы [ 2 ]

4 голосов
/ 22 августа 2011

Настройка, поэтому мы уверены, что мы говорим об одном и том же:

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

При такой логике в течение 1-й недели должно быть 6 активных сотрудников, в течение 2-й недели - 7 активных сотрудников, а на 3-й неделе - снова до 6 человек. Потребовалось несколько минут, чтобы нарисовать активные линии на листе бумаги выяснить, где я ошибся в своем запросе. Теперь давайте попробуем это на примере данных, которые мы настроили в базе данных 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;

А затем уберите:

GO
DROP TABLE dbo.[date table], dbo.users;
0 голосов
/ 22 августа 2011

Я собирался сделать что-то гораздо более простое, но я думаю, что это также сработает:

select top 8 week_end, COUNT(U.user_ID) from users U
join dates D on U.hired_date < D.week_end 
and (U.termination_date > D.week_start or U.termination_date is null)
group by week_end 
order by week_end desc

Обратите внимание, что я считаю, что вам нужно иметь дату приема на работу до week_end и дату завершения после week_start, чтобы учесть неполные недели.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...