简体   繁体   中英

Student absent for 5 consecutive days excluding Holidays

I am using code igniter and attendance table as below:

attendance ID   timestamp   student_id     status
     1           01-01-20        1           P
     2           01-01-20        2           P
     3           02-01-20        1           P
     4           02-01-20        2           A
     5           03-01-20        1           P
     6           03-01-20        2           A
     7           04-01-20        1           H
     8           04-01-20        2           H
     9           05-01-20        1           P
     10          05-01-20        2           A

My target is to get the student id who is absent for 3 consecutive days for the period of the last 1 month from today excluding the holidays in the middle like in the above table the student id 2 should be the one with 3 consecutive absence excluding the holiday on the 4th Jan.

I am using Apache/2.4.23 (Win32) OpenSSL/1.0.2h PHP/5.6.28 with mysql. I have been able to get the consecutive 3 absent but when there is a holiday in the middle, I fail to find a work around there. here is my existing code:

SELECT *,
CASE
   WHEN (@studentID  = student_id) THEN @absentRun := IF(status = A, 0, @absentRun + 1)
   WHEN (@studentID := student_id) THEN @absentRun := IF(status = A, @absentRun + 1, 0)
END AS absentRun
FROM attendance
Where timestamp BETWEEN (CURRENT_DATE() - INTERVAL 1 MONTH) AND CURRENT_DATE() AND year='2019-2020'
ORDER BY student_id, timestamp;

I would really really appreciate a quick answer from someone to help me with this. I am really hope to have a solution since I have posted here for help for the first time. Thanks in advance.

I understand this as a variant of the gaps and island problem. Here is one way to solve it using row_number() (available in MySQL 8.0) - the difference between the row numbers gives you the group each record belongs to.

select 
    student_id,
    min(timestamp) timestamp_start,
    max(timestramp) timestamp_end
from (
    select 
        t.*, 
        row_number() over(partition by student_id order by timestamp) rn1,
        row_number() over(partition by student_id, status order by timestamp) rn2
    from mytable t
) t
where status = 2
group by student_id, rn1 - rn2
having count(*) >= 5

This will give you one record for each streak of at least 5 consecutive days of absence for each student. As a bonus, the query also displays the starting and ending date of each streak.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM