Find student with the maximum average mark - mysql

i have tried a lot without success, i want to display only the maximum average of student marks from the list of student as shown on the table below.
My table
i want to get the result as below
expected output
what i have done so far
SELECT MAX(a.Total_Qty) As TotalMax,a.studentId
FROM(
SELECT AVG( s.marks ) AS Total_Qty,s.studentId
FROM results s
WHERE s.stream = 'Form One'
GROUP BY s.studentId) AS a

Inner query will give you the list of averages for each student.
Then we order (descending) by their average score and finally we get the top 1 (Limit 1)
SELECT a.studentId, a.Total_Qty as MaxAvg
FROM(
SELECT AVG( s.marks ) AS Total_Qty,s.studentId
FROM results s
WHERE s.stream = 'Form One'
GROUP BY s.studentId)
AS a
Order by a.Total_Qty Desc
Limit 1
Alternatively:
SELECT AVG( s.marks ) AS Total_Qty,s.studentId
FROM results s
WHERE s.stream = 'Form One'
GROUP BY s.studentId
Order By AVG( s.marks ) Desc
Limit 1

(UNTESTED) I hope it helps
if you are using MSSQL :
SELECT TOP(1) studentId, AVG(marks) FROM results GROUP BY studentId
ORDER BY MAX(AVG(marks)) Desc
if you are using SQL :
SELECT studentId, AVG(marks) FROM results GROUP BY studentId
ORDER BY MAX(AVG(marks)) Desc Limit 0,1

Related

Join 2 Select Queries in a Same Table in MySql

I have a Table Name Called tbl_events and it does have following columns
Id,Event_Name, District,Branch_Type,Points
I need a Sum of Points Column Where Branch_Type=2; and Sum of Points Divided by 10 Where Branch_Type=2 after that I have to Add those Two Values And Group that Result by District and Order by Desc. I tried this Query but Seems to something wrong Can anyone help, please?
Select (t1.B_Points + t2.D_Points) as T_Points,District From
(Select Sum(Points)*.1 as B_Points ,District From tblstudents Where Branch_Type=3 group by District)t1
Left Join(Select Sum(Points) as D_points, District From tblstudents Where Branch_Type=2 group by District)t2 on
(t1.District=t2.District) Order by Desc
You need to add column alias T_Points in order by
Select (t1.B_Points + t2.D_Points) as T_Points,District
From
(
Select Sum(Points)*.1 as B_Points ,District From tblstudents
Where Branch_Type=3 group by District
)t1
Left Join
(
Select Sum(Points) as D_points, District From tblstudents
Where Branch_Type=2 group by District
)t2 on t1.District=t2.District
Order by T_Points Desc
You seem to just want conditional aggregation:
select district,
sum(case when branch_type = 3 then 0.1 * points
when branch_type = 2 then points
else 0
end) as t_points
from tblstudents
group by district;
If you want to order by the points descending, then add:
order by t_points desc
Note: This assumes that you want districts that have neither branch type. If that is not an issue, move the logic to the where clause:
select district,
sum(points * (case when branch_type = 3 then 0.1 else 1.0 end) as t_points
from tblstudents
where branch_type in (2, 3)
group by district
order by t_points desc;

SQL Count Values From the Top 6

i trying to create an SQL query to count how many times [Over]='Y' in the Top 6 selection and i receive an error in the merge query.
Query to get Top 6:
SELECT TOP 6 [Number]
,[Over]
,[Goal]
FROM [Test_Hermes].[dbo].[Test]
ORDER BY Number desc
Query to count:
SELECT COUNT([Over])
FROM [dbo].[Test]
WHERE [OVER] = 'Y';
Merge both queries:
SELECT COUNT([Over])
FROM (SELECT TOP 6 [Number]
,[Over]
,[Goal]
FROM [Test_Hermes].[dbo].[Test]
ORDER BY Number desc)
WHERE [OVER] = 'Y';
any help will be appreciate!
Thanks
Show this sample pls.
SELECT
[Number]
,[Over]
,[Goal]
, SUM( If(OVER= 'Y',1,0)) AS CNT
FROM [Test_Hermes].[dbo].[Test]
ORDER BY Number desc
LIMIT 1,6;
You can not use an order by in a sub query.
SELECT COUNT([t1].[Over])
FROM (SELECT TOP 6 [Number]
,[Over]
,[Goal]
FROM [Test_Hermes].[dbo].[Test]) as t1
WHERE [OVER] = 'Y' ;
If you need the order to determine the top 6 use ROW_NUMBER()
SELECT COUNT([t1].[Over])
FROM (SELECT ROW_NUMBER() OVER(PARTITION BY [Number] ORDER BY [Number] DESC) as 'Rank'
,[Number]
,[Over]
,[Goal]
FROM [Test_Hermes].[dbo].[Test]) as t1
WHERE [t1].[OVER] = 'Y' AND [t1].[Rank] <= 6;

How to get Last and Secondlast Record from mysql table

From the above image i have n number of records with cat_id and sub_cat_id but in image only two are there.
so i want get the last and secondlast score_in_per value as named lastScore and latetsScore..
how can i retrieve that..?
SELECT
(SELECT score_in_per FROM tbl_student_skill_score ORDER BY date DESC LIMIT 2,0) as lastScore,
(SELECT score_in_per FROM tbl_student_skill_score ORDER BY date DESC LIMIT 1) as latetsScore
i am new to this complicated mysql logics..This what i have tried..
Example:
lets say one user email is inststudent#yopmail.com take the same test 2 times and the test is linked up with one category and sub category.
so the user will take the test any number of times...
from that records i want to get the last two records percentage.
If I understand you correctly; you want to select the two most recent results of a specific type of test taken by a specific student.
You don't use the LIMIT clause correctly. This is the correct syntax: LIMIT {[offset,] row_count | row_count OFFSET offset}. Also, you completely left out the where clause.
So the query should be:
SELECT
(SELECT score_in_per FROM tbl_student_skill_score
WHERE user_email = "email of the user you are interested in"
AND cat_id = categoryOfTestOfInterest
AND sub_cat_id = subcategoryOfTestOfInterest
ORDER BY date DESC LIMIT 1, 1
)AS lastScore,
(SELECT score_in_per FROM tbl_student_skill_score
WHERE user_email = "email of the user you are interested in"
AND cat_id = categoryOfTestOfInterest
AND sub_cat_id = subcategoryOfTestOfInterest
ORDER BY date DESC LIMIT 1
)AS latetsScore;
If a student can take the test multiple times a day (like your image suggests) than you should also order by id (supposing that the id is always greater for newer results) or better still, only by the id:
SELECT
(SELECT score_in_per FROM tbl_student_skill_score
WHERE user_email = "email of the user you are interested in"
AND cat_id = categoryOfTestOfInterest
AND sub_cat_id = subcategoryOfTestOfInterest
ORDER BY id DESC LIMIT 1, 1
)AS lastScore,
(SELECT score_in_per FROM tbl_student_skill_score
WHERE user_email = "email of the user you are interested in"
AND cat_id = categoryOfTestOfInterest
AND sub_cat_id = subcategoryOfTestOfInterest
ORDER BY id DESC LIMIT 1
)AS latetsScore;
One of the way of solving this problem is by using Partition By .
Step1: I have ranked the data for distinct cat_id and sub_cat_id in descending order of date by partition by.
Step2: I have used rank1 which is the latest score and merged it with rank2 which is the second last score
with chck as
(select
cat_id,sub_cat_id,score_in_per,date1,
row_number() over(partition by cat_id,sub_cat_id order by
cat_id,sub_cat_id,date1 desc) as row_num
from tbl)
select a.*,b.second_last_score from
(select cat_id,sub_cat_id,score_in_per,date1,row_num as last_score from chck where row_num=1) a
left join
(select cat_id,sub_cat_id,score_in_per,date1,row_num as second_last_score from chck where row_num=2) b
on a.cat_id = b.cat_id and a.sub_cat_id = b.sub_cat_id;
Let me know in case of any query.
SELECT
( SELECT score_in_per FROM tbl_student_skill_score WHERE cat_id=1 and sub_cat_id=5 ORDER BY date,id DESC LIMIT 1 ) AS latestScore,
( SELECT score_in_per FROM tbl_student_skill_score WHERE cat_id=1 and sub_cat_id=5 ORDER BY date,id DESC LIMIT 1,1 ) AS lastScore

SQL SCORE RANKING

I'm working with score ranking on my app for all user score. My problem is I don't know how to return one row for each stud_num.
My query:
SELECT * FROM score WHERE assess_type = 'professional' ORDER BY total_score DESC.
Result:
As you can see I have 3 stud_num and I only want one row per stud_num and the highest score of it.
You can use correlated query like this:
SELECT * FROM score t
WHERE t.assess_type = 'professional'
AND t.total_score = (select max(s.total_score)
from score s
where t.stud_num = s.stud_num)
group by stud_num
The option given by #sagi is good:
SELECT * FROM score t
WHERE t.assess_type = 'professional'
AND t.total_score = (select max(s.total_score)
from score s
where t.stud_num = s.stud_num)
group by stud_num
Another option would be to use an inner join and group by together.
The resulting query would become:
select * from score a
inner join (
SELECT stud_num, max(total_score) tscore FROM `score` group by stud_num) b
on a.stud_num = b.stud_num and total_score= tscore
group by a.stud_num
try it out at sqlfiddle
Use the MAX and GROUP BY functions like this:
SELECT score_id, stud_num, assess_type, total_item, MAX(total_score), average, date_taken
FROM score
WHERE assess_type = 'professional'
GROUP BY stud_num
ORDER BY 5 DESC
Here's my the ans:
SELECT score_id, stud_num, assess_type, total_item, MAX( total_score )
FROM score
WHERE assess_type = 'professional'
GROUP BY stud_num, total_item
ORDER BY MAX( total_score ) DESC

MySQL query for joining two queries

I have a mysql table having register number, dob, student name, sex, total mark in a semester in each row.
I would like to get records of 10 Boys and 5 girls in descending order of total marks in a single SQL query.
My MySQL dialect is rusty but this should do the trick
(SELECT * FROM Students WHERE sex = 'Male' ORDER BY TotalMarks DESC LIMIT 10)
UNION ALL
(SELECT * FROM Students WHERE sex = 'Female' ORDER BY TotalMarks DESC LIMIT 5)
It's a single query, mind you.
Try this code:
select
a.studentID,
a.studentName,
a.dob,
a.totalMark
from
(
select
studentID,
studentName,
dob,
totalMark
from
students
where
sex='M'
order by
studentMark desc
limit 10
union all
select
studentID,
studentName,
dob,
totalMark
from
students
where
sex='F'
order by
totalMark desc
limit 5
)
order by
totalMark desc
try this
select * from
(select reg_number, dob, student_name, sex, total_marks where sex='male'
order by total_marks desc limit 10
union
select reg_number, dob, student_name, sex, total_marks where sex='female'
order by total_marks desc limit 5) a order by total_marks desc