Order statistic in MySQL

This is a discussion on Order statistic in MySQL within the MySQL Database forums, part of the Database Forums category; Jeffrey Rolland wrote: > I need to drop the *two* lowest quiz grades in computing the final grade. > For ...


Go Back   Usenet Forums > Database Forums > MySQL Database

FAQ Members List Calendar Search Today's Posts Mark Forums Read
  #11 (permalink)  
Old 04-25-2006
Bill Karwin
 
Posts: n/a
Default Re: Order statistic in MySQL

Jeffrey Rolland wrote:
> I need to drop the *two* lowest quiz grades in computing the final grade.


> For instance, say I have 3 students and 4 quizzes. A sample data set
> for grade is
>
> studentID testID grade
> 1 1 10
> 1 2 8
> 1 3 10
> 1 4 7
> 2 1 10
> 2 2 9
> 2 3 10
> 2 4 8
> 3 1 6
> 3 2 4
> 3 3 6
> 3 4 5


I tried this, and it seems to work:

select s.studentid, s.testid, s.grade
from scores s
left join scores s2 on s.studentid = s2.studentid and s.testid <>
s2.testid and s.grade <= s2.grade
group by s.studentid, s.testid
having count(*) < 2

On the last line, the number 2 should be the total number of quizzes,
minus the 2 you want to drop. So instead of dropping the bottom two, we
only include the top N-2. In your sample, you have 4 quizzes, so the
value is 4-2, or 2.

I'm not sure if this matches the method by which you want to drop quizzes.

Regards,
Bill K.
Reply With Quote
  #12 (permalink)  
Old 04-25-2006
Jerry Stuckle
 
Posts: n/a
Default Re: Order statistic in MySQL

Jeffrey Rolland wrote:
> Jerry Stuckle wrote:
>
>>Jeffrey Rolland wrote:
>>
>>>Jerry Stuckle wrote:
>>>
>>>
>>>>Jeffrey Rolland wrote:
>>>>
>>>>
>>>>>Ted wrote:
>>>>>
>>>>>
>>>>>
>>>>>>If you REALLY want the two lowest grades (or more precisely the records
>>>>>>containingthe two lowest grades), you'd use ORDER BY combined with
>>>>>>LIMIT 2 in a SELECT statement.
>>>>>>
>>>>>>I suspect what you really want is to select all grades except the two
>>>>>>lowest grades.
>>>>>>
>>>>>>If you know the number of grades, you'd use an ORDER BY, along with
>>>>>>DESC (so you're sorting in descending order), combined with a LIMIT
>>>>>>with a number two less than the number of grades. If the number of
>>>>>>grades is unknown, or can vary, then you have a little extra
>>>>>>complexity, because you'd need to use count() to get the number of
>>>>>>grades before selecting all grades except the two lowest grades.
>>>>>>
>>>>>>You can look up the exact syntax in the MySQLmanual.
>>>>>>
>>>>>>I hope this helps.
>>>>>>
>>>>>>Ted
>>>>>
>>>>>
>>>>>I want all grades except the last two.
>>>>>
>>>>>Just to be clear, I want to get all grades except for the last two
>>>>>*for* *each* *record*. I think that LIMIT limits the number of records,
>>>>>not the number of grade fields in each record. It LIMIT does limit the
>>>>>number of grade fields, that would do it.
>>>>>
>>>>>I have PHP installed on my system, so a PHP/MySQL solution would also
>>>>>work (to relpy to another poster).
>>>>>
>>>>>Thanks for your replies. I will crosspost this to
>>>>>alt.comp.databases.mysql
>>>>>
>>>>>Sincerley,
>>>>>--
>>>>>Jeffrey Rolland | "Beneath this mask there is more than
>>>>><wildstar200@hotmail.com> | flesh. There is an idea, Mr. Creedy, and
>>>>>
>>>>> | ideas are bulletproof. "
>>>>> | - _V for Vendetta_
>>>>>
>>>>
>>>>Ah, now I see your problem. Like Ted I thought your data was normalized. It
>>>>looks like you just recreated your Excel tables in MySQL, which isn't very
>>>>efficient.
>>>>
>>>>Read up (try a google search) on "database normalization". The break your one
>>>>big table into several. They could be something like:
>>>>
>>>>student
>>>> studentid name
>>>>
>>>>test
>>>> testid description
>>>>
>>>>grade
>>>> studentid testid grade
>>>>
>>>>Then you'll be able to perform the search you want plus more.
>>>>
>>>>
>>>>--
>>>>==================
>>>>Remove the "x" from my email address
>>>>Jerry Stuckle
>>>>JDS Computer Training Corp.
>>>>jstucklex@attglobal.net
>>>>==================
>>>
>>>
>>>Call me stupid (or a newbie) but I don't see how normalizing helps.
>>>
>>>For instance, say I have 3 students and 4 quizzes. A sample data set
>>>for grade is
>>>
>>>studentID testID grade
>>>1 1 10
>>>1 2 8
>>>1 3 10
>>>1 4 7
>>>2 1 10
>>>2 2 9
>>>2 3 10
>>>2 4 8
>>>3 1 6
>>>3 2 4
>>>3 3 6
>>>3 4 5
>>>
>>>Now, how would LIMIT 2 or LIMIT 6 (= 3 students * top 2 records) het me
>>>what I want? How exactly are you sorting?
>>>
>>>Sorting by studentID then by grade (descending), we have
>>>
>>>studentID testID grade
>>>1 1 10
>>>1 3 10
>>>1 2 8
>>>1 4 7
>>>2 1 10
>>>2 3 10
>>>2 2 9
>>>2 4 8
>>>3 1 6
>>>3 3 6
>>>3 4 5
>>>3 2 4
>>>
>>>so the top 6 is
>>>
>>>1 1 10
>>>1 3 10
>>>1 2 8
>>>1 4 7
>>>2 1 10
>>>2 3 10
>>>
>>>not what we want.
>>>
>>>Sorting by grade (descending) then studentID we have
>>>
>>>studentID testID grade
>>>1 1 10
>>>1 3 10
>>>2 1 10
>>>2 3 10
>>>2 2 9
>>>1 2 8
>>>2 4 8
>>>1 4 7
>>>3 1 6
>>>3 3 6
>>>3 4 5
>>>3 2 4
>>>
>>>so the top 6 is
>>>
>>>1 1 10
>>>1 3 10
>>>2 1 10
>>>2 3 10
>>>2 2 9
>>>1 2 8
>>>
>>>not what we want either.
>>>
>>>Neither has the top 6 what I want.
>>>
>>>I assume I am missing something regarding how LIMIT works.
>>>
>>>Thanks in advance for any assistance you can provide.
>>>
>>>Sincerely,
>>> --
>>>Jeffrey Rolland | "Beneath this mask there is more than
>>><wildstar200@hotmail.com> | flesh. There is an idea, Mr. Creedy, and
>>> | ideas are bulletproof. "
>>> | - _V for Vendetta_
>>>

>>
>>You select only the quiz or student you want - not the entire result set. For
>>instance - if you want the top grades for student 1, you
>>
>> SELECT testID grade
>> FROM scores
>> WHERE studentID = 1
>> ORDER BY grade DESC
>> LIMIT 2
>>
>>(Assuming 4 tests)
>>
>>This gives you
>>
>> 1 10
>> 2 10
>>
>>and drops the lower two grades.
>>
>>You could do something similar for test id.
>>
>>
>>--
>>==================
>>Remove the "x" from my email address
>>Jerry Stuckle
>>JDS Computer Training Corp.
>>jstucklex@attglobal.net
>>==================

>
>
> I see; you want me to do this FOR EACH STUDENT. This will not allow me
> to create a single nice query/report for making out grades, unless I
> use views or supplement with a loop in PHP, e.g..
>
> I was actually looking for something like LEAST(quiz1, quiz2, quiz3),
> only for 2 or more. I guess that isn't going to happen.
>
> In fact, I have a situation where some quizzes are worth 30 points,
> some are worth 40, and some are worth 20; I have a "dummy student"
> record that contains what the maximum grade for each quiz is. If I'm
> doing the report in PHP anyways, I guess that would be easy enough to
> account for in there.
>
> Thanks for all the help.
>
> Sincerely,
> --
> Jeffrey Rolland | "Beneath this mask there is more than
> <wildstar200@hotmail.com> | flesh. There is an idea, Mr. Creedy, and
> | ideas are bulletproof. "
> | - _V for Vendetta_
>


You can. You can also build a UNION, i.e. (not tested)


SELECT testID grade
FROM scores
WHERE studentID = 1
ORDER BY grade DESC
LIMIT 2
UNION
SELECT testID grade
FROM scores
WHERE studentID = 2
ORDER BY grade DESC
LIMIT 2

And so on. You could use GROUP BY, but that would only work if you have the
same number of students taking each test.

But personally I think the easiest way would be to just do it in a loop and
fetch each one separately.

--
==================
Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.
jstucklex@attglobal.net
==================
Reply With Quote
  #13 (permalink)  
Old 04-25-2006
strawberry
 
Posts: n/a
Default Re: Order statistic in MySQL

And don't forget to store the scores as percentages! I think you could
do that this way...

CREATE VIEW percentages AS SELECT
results.test_id,
student_id,
round( (score / tests.max_score) *100 ) AS percent
FROM results, tests
WHERE results.test_id = tests.test_id

Reply With Quote
  #14 (permalink)  
Old 04-25-2006
Ted
 
Posts: n/a
Default Re: Order statistic in MySQL

Don't forget what the numbers mean! My understanding of the original
problem was that the students would be taking some number of quizes
that would be equally weighted, and that the two lowest marks would be
ignored. This is a fairly common practice in education, and I have
done it myself. However, it is not rational to do this across all
evaluation instruments since major projects and of course midterm and
final examinations are typically worth much more than any individual
quiz. I have been working on the assumption that Jerry is doing this
only for the quizes, and maybe for some exercises, and not for the more
significant or important evaluation instruments. The rationale for
ignoring one or two lowest marks for formative evaluation instruments
is to ensure that a student does not suffer much should he miss a class
or two and thus an exercise or two due to minor illness such as a flu.
But I can see no justification for doing this sort of thing for
summative evaluation instruments. IMHO, all marks on summative
evaluation instruments must count regardless of how well or how badly a
student has performed.

So, Strawberry, you're right you can create a view with percentages,
much as you describe, but given that the selection procedure should be
applied only in situations where, refering to your code,
tests.max_score is the same for all records, it isn't really necessary.

The fact that you can do something, using your favourite programming
language, does not imply that you should do it.

Cheers,

Ted

Reply With Quote
Reply
Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are Off
[IMG] code is Off
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On




All times are GMT +1. The time now is 09:56 AM.


Powered by vBulletin® Version 3.7.3
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Content Relevant URLs by vBSEO 3.0.0