【发布时间】:2016-11-10 10:40:38
【问题描述】:
我有一张这样的桌子......
CREATE TABLE AbsentStudents
(
Id int not null primary key identity(1,1),
StudentId int not null,
AbsentDate datetime not null
)
这是一个非常大的表格,每个学生缺勤的每一天都有 1 行。
我被要求编写一个按日期范围获取学生缺勤的存储过程。使这个查询变得棘手的是我必须通过“缺席事件”进行过滤/聚合。构成“缺勤事件”的天数是一个程序参数,因此可以变化。
因此,例如,我需要获取 2016 年 1 月 1 日至 2016 年 1 月 17 日期间缺勤的学生列表,但前提是他们缺勤时间超过 @Days(2 或 3 天或任何参数要求) ) 天。
我认为只有这一点我才能弄清楚。但是,在该日期范围内,学生可以有多个“缺勤事件”。因此,学生可能在日期范围开始时缺席 3 天,在日期范围中间缺席 2 天,在日期范围结束时缺席 4 天,并且每一个都构成不同的“缺席事件”。假设我的 @Days 参数为 2,则应该为该学生返回 3 行。并且,每个返回的行都应该计算学生在“缺勤事件”中缺勤的天数。
所以我希望我的程序需要 3 个参数(@StartDate datetime、@EndDate datetime、@Days int)并返回类似这样的内容...
StudentId、InitialAbsentDate、ConsecutiveDaysMissed
理想情况下,它会使用 SET 操作并避免使用游标。 (尽管如果这是唯一的选择,游标也可以。)
更新(由 Shnugo)
一个测试场景
DECLARE @AbsentStudents TABLE(
Id int not null primary key identity(1,1),
StudentId int not null,
AbsentDate datetime not null
);
INSERT INTO @AbsentStudents VALUES
--student 1
(1,{d'2016-10-01'}),(1,{d'2016-10-02'}),(1,{d'2016-10-03'}) --three days
,(1,{d'2016-10-05'}) --one day
,(1,{d'2016-10-07'}),(1,{d'2016-10-08'}) --two days
--student 2
,(2,{d'2016-10-01'}),(2,{d'2016-10-02'}),(2,{d'2016-10-03'}),(2,{d'2016-10-04'}) --four days
,(2,{d'2016-10-08'}),(2,{d'2016-10-09'}),(2,{d'2016-10-10'}) --three days
,(2,{d'2016-10-12'}); --one day
DECLARE @startDate DATETIME={d'2016-10-01'};
DECLARE @endDate DATETIME={d'2016-10-31'};
DECLARE @Days INT = 3;
【问题讨论】:
-
看看这篇文章。你需要的是一组连续的日期。 sqlservercentral.com/articles/T-SQL/71550
-
如果您准备了MCVE,您将对我们有很大帮助。请使用
DECLARE @AbsentStudents TABLE...和INSERT INTO @AbsentStudents VALUES...提供可复制的'N'可粘贴样本数据。显示您迄今为止尝试过的内容以及预期的输出。 -
SQL Server 的哪个版本?
-
@Shnugo 对不起,我应该说...SQL12。周末和节假日无关紧要。
标签: sql sql-server tsql aggregate