我正在努力识别本学年自定义日历(已创建)中连续缺勤 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 个连续数字,但我无法让它与错误一起工作。
假设您的日历和缺勤查询作为起点。 (还假设
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;