Unix Technical Forum

Order statistic in MySQL

This is a discussion on Order statistic in MySQL within the MySQL forums, part of the Database Server Software category; --> Hello, all! I am currently keeping my student's grades in MS Excel, but I am considering migrating to MySQL. ...


Go Back   Unix Technical Forum > Database Server Software > MySQL

Register FAQ Members List Calendar Search Today's Posts Mark Forums Read
  #1 (permalink)  
Old 02-28-2008, 07:37 AM
Jeffrey Rolland
 
Posts: n/a
Default Order statistic in MySQL

Hello, all!

I am currently keeping my student's grades in MS Excel, but I am
considering migrating to MySQL. The only problem is this: I need to
drop the *two* lowest quiz grades in computing the final grade.

Is there a way to do this in MySQL? I know how to get the *lowest* quiz
grade, but how do I compute the *two* lowset quiz grades?

Thanks in advance for any assistance you can provide.

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_

P.S. I didn't crosspost this because comp.databases.mysql isn't carried
on my newsserver, only Google.

Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #2 (permalink)  
Old 02-28-2008, 07:37 AM
Ted
 
Posts: n/a
Default Re: Order statistic in MySQL

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

Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #3 (permalink)  
Old 02-28-2008, 07:37 AM
strawberry
 
Posts: n/a
Default Re: Order statistic in MySQL

Yes, but you can't use a variable in a LIMIT satement - so this only
works if you use a bit of php to construct the query.

Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #4 (permalink)  
Old 02-28-2008, 07:37 AM
Jeffrey Rolland
 
Posts: n/a
Default Re: Order statistic in MySQL


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_

Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #5 (permalink)  
Old 02-28-2008, 07:37 AM
Ted
 
Posts: n/a
Default Re: Order statistic in MySQL

I had assumed your database was normalized. You're right, limits the
number of records. I don't know a way to limit the number of fields.
If you don't want your database normalized, you may well have to use a
PHP/MySQL solution. If I was developing such an application, I'd have
a grades table structured so that there is one record for each
evaluation event (whether a quiz, assignment, examination &c.), in
which the limit clause would work.

Ted.

Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #6 (permalink)  
Old 02-28-2008, 07:37 AM
strawberry
 
Posts: n/a
Default Re: Order statistic in MySQL

I think "subtract lowest two from total" and "all but the lowest two"
are two ways of saying exactly the same thing, so that's not the issue.

Ted's right though - you should normalize your table when you pull it
in to php, but regardless of whether you normalize it or not, you will
still need to use PHP to construct the query - unless (and, as a
newcomer to mysql myself, this is entirely possible), Ted, you know
something I don't!

My longwinded answer to another question in this NG (see
comp.databases.mysql/browse_thread/thread/9893fdeb1aef4dfa)
attempts to solve a not entirely unrelated problem. Significantly, it
shows how the results of a count(*) statement can be used to assign a
variable to the LIMIT part of a subsequent query. Someone's going to
come long in a minute with a much smarter and more elegant solution
but, until they do, perhaps this will help some way to solving your
problem.

Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #7 (permalink)  
Old 02-28-2008, 07:37 AM
Jerry Stuckle
 
Posts: n/a
Default Re: Order statistic in MySQL

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
==================
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #8 (permalink)  
Old 02-28-2008, 07:38 AM
Jeffrey Rolland
 
Posts: n/a
Default Re: Order statistic in MySQL

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_

Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #9 (permalink)  
Old 02-28-2008, 07:38 AM
Peter H. Coffin
 
Posts: n/a
Default Re: Order statistic in MySQL

On 23 Apr 2006 10:47:46 -0700, 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).


That's handy, because if what I understand you wanting to do is correct,
you're going to run into a scope issue trying to do this as a single
query.

First, you'll need to query your student table to get a unique list of
the students. Then, use php loop driven by that result set to

SELECT * FROM tbl WHERE student_id = ?
ORDER BY grade LIMIT 2,18446744073709551615 ;

where ? is the student ID from your driver result set. The big number
that's the second parameter in the LIMIT is an arbitrarily large number.
For grades, even 1000 is probably overkill. You just want it to be at
least two more than the number of grades each student has. (Whether you
want to do a real prepare/execute or just do it via php substitution in
a concatenated string used as the query is up to you. For the number of
students in a class (or even a whole school) you'll probably not run
into a case where the overhead saved by prepare/execute matters much.)

--
They got rid of it because they judged it more trouble than it was worth.
(And considering they'd gone to great lengths to minimize its worth,
I suppose they were right.)
-- J. D. Baldwin
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #10 (permalink)  
Old 02-28-2008, 07:38 AM
Jerry Stuckle
 
Posts: n/a
Default Re: Order statistic in MySQL

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
==================
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
Reply


Thread Tools
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

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On
Forum Jump


All times are GMT. The time now is 03:05 PM.


Powered by vBulletin® Version 3.6.5
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
SEO by vBSEO 3.2.0
www.UnixAdminTalk.com