I’m using MySQL 8.0
Table NameL: sc (score)
Columns: student_id, course_id, score
Some dummy data:
create table sc(SId varchar(10),CId varchar(10),score decimal(18,1));
insert into sc values('01' , '01' , 80);
insert into sc values('01' , '02' , 90);
insert into sc values('01' , '03' , 99);
insert into sc values('02' , '01' , 70);
insert into sc values('02' , '02' , 60);
insert into sc values('02' , '03' , 80);
insert into sc values('03' , '01' , 80);
insert into sc values('03' , '02' , 80);
insert into sc values('03' , '03' , 80);
insert into sc values('04' , '01' , 50);
insert into sc values('04' , '02' , 30);
insert into sc values('04' , '03' , 20);
insert into sc values('05' , '01' , 76);
insert into sc values('05' , '02' , 87);
insert into sc values('06' , '01' , 31);
insert into sc values('06' , '03' , 34);
insert into sc values('07' , '02' , 89);
insert into sc values('07' , '03' , 98);
The question is: Output all the scores and the average scores of each student, and order the results in descending order of average score.
I came up with two solutions:
-- Solution 1
SELECT
sc.*,
AVG(score) OVER (PARTITION BY sid) AS avg_score
FROM sc
ORDER BY avg_score DESC
-- Solution 2
select * from sc
left join (
select sid,avg(score) as avscore from sc
group by sid
)r
on sc.sid = r.sid
order by avscore desc;
2
Answers
If you add this to the table, it is likely that Solution 2 might shine:
I did a small test using your data and queries, but came up with an indeterminate result. (I checked the session status ‘Handler%’ values.)
I prefer this variation of 2:
select *
FROM (
select sid,avg(score) as avscore from sc
group by sid
) AS r
JOIN sc USING(sid)
order by avscore desc;
Suggest you try with a million rows.
Here’s a technique for checking performance when you only have a small subset of the data:
— Solution 1
Handlers:
— Solution 2
Handlers:
I deduce that the
OVER
approach is twice as slow.Windowing functions are useful in some situations where there is essentially no other way to achieve a goal, but I have not found them to be faster when there is an alternative.