查询连续缺勤3次的学生-自定义日历

问题描述 投票:0回答:1

我正在努力识别本学年自定义日历(已创建)中连续缺勤 3 次或以上的学生。

我这里有一个自定义日历的临时表:

SELECT 
cal.CAL_DATE
, ROW_NUMBER() OVER (PARTITION BY cal.SCHOOL_YEAR_GU ORDER BY cal.CAL_DATE asc) rn

FROM Rev.EPC_SCH_ATT_CAL cal
JOIN rev.REV_ORGANIZATION_YEAR oy ON cal.SCHOOL_YEAR_GU = oy.ORGANIZATION_YEAR_GU
JOIN rev.REV_YEAR yr ON oy.YEAR_GU = yr.YEAR_GU

 WHERE cal.ROTATION = 'I'

AND yr.YEAR_GU = (SELECT YEAR_GU FROM rev.SIF_22_Common_CurrentYearGU) e

我有第二个查询,显示学生缺勤日期:

SELECT 
  org.ORGANIZATION_NAME AS School 
, stu.SIS_NUMBER AS PermID 
, per.LAST_NAME + ', ' + per.FIRST_NAME AS Name 
, grd.VALUE_DESCRIPTION AS Grade 
, FORMAT (att.ABS_DATE, 'MM/dd/yyyy') AS 'AbsDate' 
, abscd.ABBREVIATION 

FROM rev.EPC_STU stu 
JOIN rev.REV_PERSON per ON stu.STUDENT_GU = per.PERSON_GU
......

WHERE 
ssy.STATUS IS NULL 
AND yr.YEAR_GU = (SELECT YEAR_GU FROM rev.SIF_22_Common_CurrentYearGU) 

目的是加入分配给校准日期的行号,并在学生缺勤日期加入该行号, 然后使用“孤岛”技术来识别 3 个以上的缺勤。

我似乎无法从我读过的其他问题中找到完成此任务的方法。

我尝试将临时表(标识校准日期和行号)与显示学生缺勤的查询连接起来,将行号分配给缺勤日期,然后使用孤岛技术查找每个学生缺勤的 3 个连续数字,但我无法让它与错误一起工作。

sql gaps-and-islands temp
1个回答
0
投票

假设您的日历和缺勤查询作为起点。 (还假设

PermID
代表学生 ID 号。)您只需加入常见日期,然后查找序列中的间隙即可找到一系列日期的开始位置。您似乎打算将上课日连续编号,以便将周末和节假日的缺勤视为同一日期的一部分:

with calendar as (
    SELECT 
          cal.CAL_DATE
        , ROW_NUMBER() OVER (PARTITION BY cal.SCHOOL_YEAR_GU
                             ORDER BY cal.CAL_DATE asc) rn
    FROM Rev.EPC_SCH_ATT_CAL cal
    JOIN rev.REV_ORGANIZATION_YEAR oy ON cal.SCHOOL_YEAR_GU = oy.ORGANIZATION_YEAR_GU
    JOIN rev.REV_YEAR yr ON oy.YEAR_GU = yr.YEAR_GU
    WHERE cal.ROTATION = 'I'
    AND yr.YEAR_GU = (SELECT YEAR_GU FROM rev.SIF_22_Common_CurrentYearGU) e
), absences as (
    SELECT 
          org.ORGANIZATION_NAME AS School 
        , stu.SIS_NUMBER AS PermID 
        , per.LAST_NAME + ', ' + per.FIRST_NAME AS Name 
        , grd.VALUE_DESCRIPTION AS Grade
        , att.ABS_DATE
        , abscd.ABBREVIATION 
     FROM rev.EPC_STU stu 
     JOIN rev.REV_PERSON per ON stu.STUDENT_GU = per.PERSON_GU
     WHERE ssy.STATUS IS NULL 
     AND yr.YEAR_GU = (SELECT YEAR_GU FROM rev.SIF_22_Common_CurrentYearGU)
), flagged as (
    select *
        , case when rn - lag(rn) over (partition by PermID order by rn) = 1
               then 0 else 1 end as isDateGap
    from absences a inner join calendar c
        on c.CAL_DATE = a.ABS_DATE
), grouped as (
    select *
        , sum(isDateGap) over (partition by PermID order by rn) as grp
    from flagged
)
select PermID, count(*) as num_consecutive_absence,
    min(ABS_DATE) as first_absence, max(ABS_DATE) as last_absence
from grouped
group by PermID, grp
having count(*) >= 3;
© www.soinside.com 2019 - 2024. All rights reserved.