Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/jquery-ui/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SQL Server:查找自定义日期内学生的连续缺勤计数_Sql_Sql Server_Tsql - Fatal编程技术网

SQL Server:查找自定义日期内学生的连续缺勤计数

SQL Server:查找自定义日期内学生的连续缺勤计数,sql,sql-server,tsql,Sql,Sql Server,Tsql,我有一张桌子,上面放着学生每天的出席人数。我需要找连续缺席3天的学生。然而,出勤日期不按顺序排列,有些日子如不出勤、节假日、周末不包括在内。学生上课的日期是该表中记录的日期 数据如下 StudentId Date Attendance ----------------------------------------- 178234 1/1/2017 P 178234 5/1/2107 A 17

我有一张桌子,上面放着学生每天的出席人数。我需要找连续缺席3天的学生。然而,出勤日期不按顺序排列,有些日子如不出勤、节假日、周末不包括在内。学生上课的日期是该表中记录的日期

数据如下

StudentId       Date           Attendance
-----------------------------------------
178234          1/1/2017          P
178234          5/1/2107          A
178234          6/1/2107          A
178234          11/1/2107         A
178432          1/1/2107          P
178432          5/1/2107          A
178432          6/1/2107          P
178432          11/1/2107         A
在上述情况下,结果应为

StudentId        AbsenceStartDate     AbsenceEndDate     ConsecutiveAbsences
----------------------------------------------------------------------------
178234           5/1/2017             11/1/2017           3

我已经尝试过实现这个解决方案,但是它只对日期起作用。任何建议都很好,谢谢。哦,你的桌子上有缺席和礼物。您可以使用
行数()的差异
方法:

select studentid, min(date), max(date)
from (select a.*,
             row_number() over (partition by studentid order by date) as seqnum,
             row_number() over (partition by studentid, attendance order by date) as seqnum_a
      from attendance a
     ) a
where attendance = 'A'
group by studentid, (seqnum - seqnum_a)
having count(*) >= 3;
行号之差得到相同的连续值。这有点难理解,但是如果您运行子查询,您应该看到对于连续缺席或出席,差异是如何保持不变的。您只关心缺勤,因此外部查询中的
where

尝试以下操作:

declare @t table (sid int, d date, att char(1))
insert @t (sid,d, att) values
(178234, '1/1/2017','P'),
(178234, '5/1/2017','A'),
(178234, '6/1/2017','A'),
(178234, '11/1/2017','A'),
(178432, '1/1/2017','P'),
(178432, '5/1/2017','A'),
(178432, '6/1/2017','P'),
(178432, '11/1/2017','A')

Select s.sid, Min(s.d) startDt, Max(e.d) endDt, s.att, e.att, count(*)
from @t s join @t e on e.d <=  
   (select max(d) from @t m
    Where sid = s.sid
       and d > s.d
       and att = 'A'
       and not exists 
          (Select * from @t
           where sid = s.sid
              and d between s.d and m.d
              and att = 'P'))
Where s.att = 'A' 
   and s.d = (Select Min(d) from @t
              Where sid = s.sid
                and d < e.d
                and att = 'A')
group by s.sid, s.d, s.att, e.att
declare@t表(sid int,d日期,att char(1))
插入@t(sid、d、att)值
(178234,'2017年1月1日','P'),
(178234,'2017年5月1日','A'),
(178234,'6/1/2017','A'),
(178234,'2017年11月1日','A'),
(178432,“2017年1月1日”,“P”),
(178432,'5/1/2017','A'),
(178432,'6/1/2017','P'),
(178432,‘2017年11月1日’,‘A’)
选择s.sid、最小(s.d)开始时间、最大(e.d)结束时间、s.att、e.att、计数(*)
从@t s在e.d s.d上加入@t e
和att='A'
而且不存在
(从@t中选择*
其中sid=s.sid
d在s.d和m.d之间
和att='P'))
其中s.att='A'
和s.d=(从@t中选择Min(d)
其中sid=s.sid
d
这也很难解释: 基本上,它使用别名s(表示开始)和e(表示结束)将表连接到自身,其中s行是一组连续缺勤中的第一行,而e行是。行是指在螺柱出现的下一个日期之前的所有缺勤。这将生成一组内没有P行的所有“a”。然后,sql按适当的值分组,以返回每个组中最早和最晚的日期以及行数。

最后一个where子句确保s行是组中的第一行。

学生出席的日期是该表中存在记录的日期。要确认,学生本应出席的所有日期都记录在该表中,
出席
列告诉您他们是否出席(p)(A) 在那一天?这可能会帮助我得到一个很好的答案,我花了一些时间才真正理解。