Sql server 对前8周的每一周的活动用户总数进行分组
我需要生成一份报告,如下所示:Sql server 对前8周的每一周的活动用户总数进行分组,sql-server,sql-server-2008,Sql Server,Sql Server 2008,我需要生成一份报告,如下所示: week-ending date | number of active users 8/6/2011 78 8/13/2011 98 8/20/2011 79 我有一个名为users的表,其中包含这些字段 用户id 租用日期 终止日期 你是活跃的吗 我也有一个我计划加入的前8周的日期表 周开始 周末 周数 我陷入了如何获得活跃用户的困境。我如何对他们进行分组,
week-ending date | number of active users
8/6/2011 78
8/13/2011 98
8/20/2011 79
我有一个名为users的表,其中包含这些字段
- 用户id
- 租用日期
- 终止日期
- 你是活跃的吗
- 周开始
- 周末
- 周数
SQL Server 2008安装程序,因此我们确信我们谈论的是同一件事:
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
按照这个逻辑,在第一周应该有6名在职员工,在第二周应该有7名在职员工,在第三周又回到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;
我本来想做一些简单得多的事情,但我认为这也行:
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
选择前8个周末,从用户中统计(用户ID)
加入日期D在美国雇佣日D.周开始或U.终止日期为空)
每周分组(完)
按周结束说明订购
请注意,我认为您需要在周结束之前有雇用日期,在周开始之后有终止日期,以说明部分周。可以安全地假设,对于任何日期,如果雇用日期更早,终止日期为空或更晚,则用户处于活动状态?换句话说,我假设is_active标志基于当前状态,因此对本报告没有用处?正确,这是一个安全的假设+1-合并或案例对当前就业检查更有效吗?我根据@nycdan的评论在这里做了一些假设。如果这没有得到你想要的数量,你需要更好地定义你如何衡量一个用户在一周内是否“活跃”。我认为这意味着他们整个星期都很活跃。如果这意味着在那一周的任何时候都要积极活动,那么你可以改变或。我还对问题中包含的“是否活跃”感到困惑。该列的当前状态是否影响用户是否包含在8周前、7周前等的结果中。?这似乎是一个特定时间点的状态。@JNK您能在查询中添加一个注释掉的行来说明您的意思吗?内部
COALESCE
将精确地转换为您提供的CASE
结构,而无需键入。至于部分周,我确实在我的评论中提到了这一点-应该很容易将和更改为或,以实现该功能(或者可能像您在问题中所做的那样交换值-同样,要求不明确)。PS我使用了外部连接,因为在给定的一周内可能有0个活动用户-不太可能,但谁知道该公司是什么样的。例如,如果他们在5周前清理了所有员工…:-)@纽约:有一点不同。假设DATE
(或DATETIME
有午夜/无时间),您的查询将丢失边界上发生的一些行,因为它使用而不是=。例如,如果将第7个用户(2007年8月雇佣)改为2012年8月雇佣,则第1周中不再包含他们。
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