简体   繁体   中英

Can't figure out a proper MySQL query

I have a table with the following structure:

id | workerID | materialID | date | materialGathered

Different workers contribute different amounts of different material per day. A single worker can only contribute once a day, but not necessarily every day.

What I need to do is to figure out which of them was the most productive and which of them was the least productive, while it is supposed to be measured as AVG() material gathered per day.

I honestly have no idea how to do that, so I'll appreciate any help.

EDIT1:

Some sample data

1 | 1 | 2013-01-20 | 25
2 | 1 | 2013-01-21 | 15
3 | 1 | 2013-01-22 | 17
4 | 1 | 2013-01-25 | 28
5 | 2 | 2013-01-20 | 23
6 | 2 | 2013-01-21 | 21
7 | 3 | 2013-01-22 | 17
8 | 3 | 2013-01-24 | 15
9 | 3 | 2013-01-25 | 19

Doesn't really matter how the output looks, to be honest. Maybe a simple table like that:

workerID | avgMaterialGatheredPerDay

And I didn't really attempt anything because I literally have no idea, haha.

EDIT2:

Any time period that is in the table (from earliest to latest date in the table) is considered.

Material doesn't matter at the moment. Only the arbitrary units in the materialGathered column matter.

As in your comments you say that we look at each worker and consider their avarage daily working skill, rather than checking which worked most in a given time, the answer is rather easy: Group by workerid to get a result record per worker, use AVG to get their avarage amount:

select workerid, avg(materialgathered) as avg_gathered
from work
group by workerid;

Now to the best and worst workers. These can be more than two. So you cannot just take the first or last record, but need to know the maximum and the minimum avg_gathered.

select max(avg_gathered) as max_avg_gathered, min(avg_gathered) as min_avg_gathered
from
(
  select avg(materialgathered) as avg_gathered
  from work
  group by workerid
);

Now join the two queries to get all workers that worked the avarage minimum or maximum:

select work.*
from
(
  select workerid, avg(materialgathered) as avg_gathered
  from work
  group by workerid
) as worker
inner join
(
  select max(avg_gathered) as max_avg_gathered, min(avg_gathered) as min_avg_gathered
  from
  (
    select avg(materialgathered) as avg_gathered
    from work
    group by workerid
  )
) as worked on worker.avg_gathered in (worked.max_avg_gathered, worked.min_avg_gathered)
order by worker.avg_gathered;

There are other ways to do this. For example with HAVING avg(materialgathered) IN (select min(avg_gathered)...) OR avg(materialgathered) IN (select max(avg_gathered)...) instead of a join. The join is very effective though, because you need just one select for both min and max.

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