1

I have an Attendance system in one of my module project using PHP and MySQL, the MySQL table looks something like this:

My Three MySQL tables

Now, timetable is used to store the Time Table for classes in a day for a section and which teacher is assigned to it. The student_info table contains general information about students and the section they belong to. The attendancetable is used to record those who are absent using time and student id as primary key.

I could get a count of how many classes were taken in a semester as follows:

SELECT count(*) as total FROM timetable WHERE flag > ? AND semester = ? AND section = ? AND timeid BETWEEN ? AND ?

Then computed how many times a student attended and also calculate the percentage of attendance.

SELECT stu.* , 
    (SELECT COUNT(*) 
    FROM attendancetable    att 
    WHERE att.s_id = stu.class_roll
    AND att.semester = ?
    AND att.timeid BETWEEN ? AND ? ) AS absent
FROM student_info   stu
WHERE stu.section = ?
AND stu.logYear = ?
AND stu.deleted = ?
ORDER BY stu.class_roll

Now, I want to also display a kind of attendance sheet as follows:

proposed output

I tried SQL Inner Join but didn't get the way I wanted.

I was thinking that the first row can be output form the following query:

SELECT timeid 
FROM timetable 
WHERE flag > ? 
  AND semester = ? 
  AND section = ? 
  AND timeid BETWEEN ? AND ?

[UPDATE] Found a way to do this, given as an answer, don't know if that's the right way.

Thank You in advance for helping.

4
  • Is my question too vague or what happened? I haven't got a response or help. Or did I do something wrong with my initial tables? Do I need to re do my database set up? Anyone can help please... Commented Mar 21, 2017 at 18:46
  • have you found any solution ? I am exactly looking the same thing.... Commented May 18, 2017 at 23:46
  • @query not yet. will be updating if I find one. Commented May 20, 2017 at 2:58
  • @query I did find some solution, do check and give comments. Commented Aug 7, 2017 at 10:18

2 Answers 2

1

I am probably a bit late with my answer, but I have been playing around a bit too and came up with a solution that is largely done within MySql: my solution builds a dynamic SELECT statement that is executed at the end to provide me with the table, having columns spanning a predefined era:

SET @str='SELECT sid';
SELECT @str:=concat(@str,', MAX(CASE tid WHEN ',t_id,
                    ' THEN \'OK\' ELSE \'\' END) d',t_id) 
--                            start date          end date
FROM times WHERE dati BETWEEN '20170810.0000' and '20171022.2359';
SET @str=concat(@str,' FROM att GROUP BY sid');
PREPARE qu FROM @str;
EXECUTE qu;

What still needs to be done is the translation of date Ids in the column headings to proper dates and, likewise, the translation of student Ids into names or univ_roll numbers.

i have also taken the liberty of changing the table layout a little bit: the primary key in the timetable is now just an integer, the actual time is stored separately in another column, providing flexibility in case dates or times might change.

Here is a little rextester demo: http://rextester.com/LPFF99061 (the attendance table has only been filled for the first few dates).

Sign up to request clarification or add additional context in comments.

1 Comment

as the saying goes "better late than never", thanks for sharing. Your solution seems better. I'll try this. I need to learn more about mysql it seems.
0

I'm not sure if I should edit the question with these updates. But this is a partial solution that I did come out with. Would be glad if someone could help optimize this more.

So, I started with this piece of code.

SELECT timeid 
FROM timetable 
WHERE flag > ? 
  AND semester = ? 
  AND section = ? 
  AND timeid BETWEEN ? AND ?

From the above code I could get the dates where classes are taken. Next, I check if a student is present or absent on the dates mentioned as follows:

SELECT attended FROM attendancetable
    WHERE s_id = ?
    AND semester = ?
    AND timeid = ?

With this I was able to see if a student is absent or not. In php it look something like this:

//Getting the dates
$query = "SELECT timeid FROM timetable
        WHERE flag > ?
        AND semester = ?
        AND section = ?
        AND timeid BETWEEN ? AND ?";
$params = array(0, 1, 'A', '2017-01-01', '2017-06-30' );
$stmt = $db->prepare($query);
$stmt->execute($params);
$dates = $stmt->fetchall();

//checking if students is present or absent
$query = "SELECT attended FROM attendancetable
        WHERE s_id = ?
        AND semester = ?
        AND timeid = ?";

//Now I'm going to loop through the $dates
foreach($dates as $date){
    $params = array(1, 'A', $date['timeid']);
    $stmt = $db->prepare($query);
    $stmt->execute($params);
    $result = $stmt->fetchall();
    ($result) ? $present = 1 : $present = 0;
}

In the above way, I was able to compute if a student of a particular section is present/absent for a given class as per the timetable. Now, if I want for all the students in a section I could first query the student_info table and then compute the foreach loop for each individual student

SELECT class_roll FROM student_info
    WHERE logYear = ?
    AND section = ?
    AND deleted = ? 
    ORDER BY class_roll LIMIT ?, ?

Each student is then run through the foreach loop to check if they are absent or present. Finally, I could get this:

Details of attendance for each class attended by students

I tested the execution time locally for about 200 students it came to about 1.6 seconds when the number of classes is only 39. I do test from previous data also for a whole semester and the code exceed 30 seconds and max_execution_time error triggered. As of now, I set a 25 number of students limits per page.

UPDATE: The max_execution_time error seems to appear only on the first run, but later when I try to re-produce its not giving anymore error and the time taken to complete the task is below 2 seconds.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.