对前8周的每个活动用户进行分组

时间:2011-08-22 17:04:15

标签: sql-server sql-server-2008

我需要生成如下报告:

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_start
  • week_end
  • WEEK_NUM

我陷入了如何获得活跃用户的困境。我如何对它们进行分组,因为我尝试了一些带有datepart的东西,它给出了一周内新用户的数量(例如,在第7周雇用的4个用户),这不是我需要的。我可以在这里使用一些指导。提前谢谢。

SQL Server 2008

2 个答案:

答案 0 :(得分:4)

设置,所以我们确定我们正在谈论同样的事情:

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;

答案 1 :(得分:0)

我想要更简单的事情,但我认为这也会有效:

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_start之前的工作日期之前和在工作周期之后的终止日期之间使用日期来计算部分工作时间。