Search code examples
sqlmysqlaggregate-functions

Multiple aggregates in a SELECT statement in MySQL


I have a table like this (Start and end time are epoch seconds)

Job_ID Job_Type Start_Time End_Time
123 A 1234567890 1234567890
123 A 1234567890 1234567890
456 B 1234567890 1234567890
456 B 1234567890 1234567890
789 A 1234567890 1234567890
789 A 1234567890 1234567890
012 B 1234567890 1234567890
012 B 1234567890 1234567890

What I would like to do is write a SELECT which first sums the total work time for each Job_ID, then it takes the average of total work time, grouped by Job_Type.

Output:

Job_Type Avg_Total_Time
A 12345
B 12345

There are more than two work types - this is just an example.

To make matters more complex, I'm working in a JDBC environment and can't actually do things like create user variables and such.

I devised a way to do this by manually selecting each work type string literal and then using two sub selects to get total times and total jobs. The problem is that this isn't dynamic or scalable, and I'm not sure how to encompass this logic any other way.

I know I need to GROUP BY the Job_Type column, but I'm not sure how to get the times summed up before taking the average of them all.

My "Working" approach which is not scalable nor dynamic:

SELECT
'A' AS `Job_Type`,
-- Total Time worked for all Type A
ROUND(
    (
        SELECT SUM(End_time - Start_time) FROM MyTable
        WHERE Job_Type = 'A'
    )
    /
-- Divide by total Jobs of type A
    (
        SELECT COUNT(Job_ID) FROM MyTable
        WHERE Job_Type = 'A'
    )
) AS `Avg_Total_Time`

UNION

SELECT
'B' AS `Job_Type`,
ROUND(
    (
        SELECT SUM(End_time - Start_time) FROM MyTable
        WHERE Job_Type = 'B'
    )
    /
-- Divide by total Jobs of type B
    (
        SELECT COUNT(Job_ID) FROM MyTable
        WHERE Job_Type = 'B'
    )
) AS `Avg_Total_Time`

Solution

  • You just need to sum the time for each job id in a subquery, and then you can calculate the average time for each job type in the outer query:

    select Job_Type, avg(job_duration)
    from (
        select Job_Type, sum(End_Time-Start_Time) job_duration
        from MyTable
        group by Job_ID, Job_Type
    ) job_durations
    group by Job_Type