简体   繁体   中英

how can i calculate the percentage of attendance from mysql using php

I am trying to develop a simple php attendance system but I am stuck. I want to generate an attendance report from the attendance table in this form:

sid | present(%) | late(%) | permission(%) | absent (%) |
    |            |         |               |            |

the problem I encountered is that I can't calculate the percentage for all students in the attendance table. The structure of my attendance table is:

sid| course | smister| section | attendance_status | date |
   |        |        |         |                   |      |

the code could be like :

$query=slect * from attendance where course=course And semister = semister and section = section;
     $result=mysqli_query(..,..);
while($row=$result_>fetch_assoc()){

//here calculate all selected students ateendance status in the above form

}

我的出勤表结构

If you want to do it in PHP, seems like you would need to "count" the number occurrences of "present", "late", "permission" and "absent" records, along with the total number of records. And that for each sid (which we presume is the student id).

Order the rows by sid , and use normal control break processing. When we get a row for a sid that differs from the previous row, we're done with the previous sid , so emit all of the counters, and do whatever calculations.

Then reset the counters, ready for accumulating this new student.

I suggest working it as a simpler problem, for example, just counting the number of rows for each sid . Once that is working, the same pattern can be expanded to keep multiple counters, and to conditionally increment the counters based on information in the row. (For example, increment the "absent" counter only for rows that indicate an absence.


Another alternative would be to entirely avoid the rigmarole in PHP and just have SQL return the result, using conditional aggregation.

The simplest form, to get the count of rows for each sid

SELECT a.sid 
     , COUNT(*) AS tot
  FROM attendance a
 GROUP BY a.sid
 ORDER BY a.sid

Add appropriate WHERE clause (before the GROUP BY clause) to limit which rows we're looking at.

We could extend that same pattern, to get other counts, based on conditions. We're just guessing at what columns are availabe in the attendance table, and how we determine if the row indicates an absence...

SELECT a.sid 
     , SUM(1)   AS tot
     , SUM(a.attendance_code = 'Absent') AS cnt_absent
     , SUM(a.attendance_code = 'Tardy' ) AS cnt_late 

     , 100.0 
     * SUM(a.attendance_code = 'Absent')
     / SUM(1)                            AS pct_absent

     , 100.0 
     * SUM(a.attendance_code = 'Tardy' )
     / SUM(1)                            AS pct_late 

  FROM attendance a
 GROUP BY a.sid
 ORDER BY a.sid

try this

SELECT sid,
    ROUND((SUM(CASE WHEN attendance_status = 'Present' THEN 1 ELSE 0 END)/COUNT(*)*100),2) as present,
    ROUND((SUM(CASE WHEN attendance_status = 'Late' THEN 1 ELSE 0 END)/COUNT(*)*100),2) as late,
    ROUND((SUM(CASE WHEN attendance_status = 'Permission' THEN 1 ELSE 0 END)/COUNT(*)*100),2) as permission,
    ROUND((SUM(CASE WHEN attendance_status = 'Absent' THEN 1 ELSE 0 END)/COUNT(*)*100),2) as absent
FROM attendance 
GROUP BY sid

working demo : http://sqlfiddle.com/#!9/35921c6/1

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