mercredi 22 juin 2016

SQL query time difference when adding an inner join and group by gives wrong calculations

Am trying to come up with an sql query to calculate, the time difference from a start time and an end time, then sum up the duration for each school.

I have the following table :

  1. -Class /*Contains all the classes tied to a school using school_id */
  2. -School /*contains all the schools in tied to a hub using hub_id */
  3. -Hub /*contains all the hubs details (one hub can have many schools in it) */
  4. -student /*contains student profile, which is tied to a class using class_id */
  5. -session_details /contains the session details which include the session start time, end time, session_id,/
  6. -student_attendance_register /* used to mark the register for all the students in a class for a particular session using session_id and student_id as in_attendance=0 or in_attendance =1 /*

I have a mini query which works perfect, the query calculates the duration of the session and finds the total duration for all the classes in a school.

select
 c.class_name,c.school_id,d.school_name,e.session_date,e.time_finish,e.time_start,
 CAST(sum(TIMEDIFF(e.time_finish, e.time_start)) as TIME) as duration 
 From session_details as e
                Inner join class as c
                    on c.id = e.class_id
                Inner join school as d 
                    on c.school_id = d.id       
                    group by c.school_id;

My problem pops up when i add inner joins to get the student profile and their attendance. See below my query

select 
    a.session_details_id,c.class_name,c.school_id,d.school_name,
    e.class_id,e.session_date,e.time_finish,e.time_start,
    SUM((TIME_TO_SEC(e.time_finish) - TIME_TO_SEC(e.time_start))/60) as session_duration,
                     COUNT(CASE WHEN a.in_attendance = 1 and b.gender = 1 then 1 END) as boys_present,
                    COUNT(CASE WHEN a.in_attendance = 1 and b.gender = 2 then 1 END) as girls_present,
                    COUNT(CASE WHEN a.in_attendance = 0 and b.gender = 1 then 1 END) as boys_absent,
                    COUNT(CASE WHEN a.in_attendance = 0 and b.gender = 2 then 1 END) as girls_absent,
                    COUNT(CASE WHEN  b.gender = 2 then 1 END) as girls_total,
                    COUNT(CASE WHEN  b.gender = 1 then 1 END) as boys_total
                    from session_details as e
                        inner join class as c
                            on c.id = e.class_id
                        inner join school as d 
                            on c.school_id = d.id
                    inner join attendance_student as a
                            on e.id = a.session_details_id
                    inner join student as b
                            on a.student_id = b.id
                    group by c.school_id;

Image 1 shows the results set without with group for all session that were done for each class in a school. This returns correct time duration.

Image 1 shows the results set without with group for all session that were done for each class in a school. This returns correct time duration.

Image 2 shows the result set with group for all session that we done for each class in a school. Image 2 shows the result set with group for all session that we done for each class in a school.

When running query 2, whereby which is an extension of query one for adding the student profile and the total no of students who were in attendance.

When running query 2, whereby which is an extension of query one for adding the student profile and the total no of students who were in attendance.

When running query 2,without grouping by shool_id i get the following results When running query 2,without grouping by shool_id i get the following results

Note -I have tried to change the time to seconds then do the division then convert to minutes which return the wrong total.

sum((TIME_TO_SEC(e.time_finish) - TIME_TO_SEC(e.time_start)))/60 as duration

-I have also tried to do a sum for the time finish in second, subtract the finish and start time then divide the total

-Am also in doubt of how am doing my inner joins, and maybe the problem lies in there, since once i introduce the inner joins to students i get the errors. Other totals are working ok except for my finish and start time which are time data type on the database.

Here is a link to the related tables.

Kindly assit on how best to go about doing a correct calculation for the duration once i inner join and group the tables. :)

http://sqlfiddle.com/#!9/36bb8/2

Aucun commentaire:

Enregistrer un commentaire