SQL SCORE RANKING - mysql

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

Related

Get maximum value from two values

I have a table which gives the no of rides by a rider at each stand point. I need to find the stand for each rider for which he has the maximum rides.
My first result is in this format: 1
I require my final result like this: 2
I'm currently using this query, but I know it can be done in a better manner. Any suggestions would be helpful.
select c.rider_id, c.end_stand, b.max_rides
from
(select rider_id, max(rides) as max_rides
from
(select rider_id, end_stand, count(id) as rides
from ride where end_stand is not null
group by 1,2) a
group by 1
order by 2 desc, 1) b
join
(select rider_id, end_stand, count(id) as rides
from ride where end_stand is not null
group by 1,2) c
on c.rider_id = b.rider_id and c.rides = b.max_rides
order by 3 desc, 2,1
Before window functions, one method is a correlated subquery in the having clause:
select rider_id, end_stand, count(*) as rides
from ride r
where end_stand is not null
group by rider_id, end_stand
having count(*) = (select count(*)
from ride r2
where r2.end_stand is not null and
r2.rider_id = r.rider_id
group by r2.rider_id, r2.end_stand
order by count(*) desc
limit 1
);
With window functions, this is, of course, much simpler:
select *
from (select rider_id, end_stand, count(*) as rides
rank() over (partition by rider_id order by count(*) desc) as seqnum
from ride r
where end_stand is not null
group by rider_id, end_stand
) r
where seqnum = 1;
Both these will return duplicates, if there are ties for the max. The second version is easy to fix, if you want only one row: use row_number() instead of rank().

how to find index ( id ) of generic column in mysql

I have a table with name rating as this.
I am writing the query like this
SELECT user_id, sum(score) as score
FROM quiz_rashad.rating
group by user_id
order by score desc
then how I get rating index of the 12th user?
Thank you for helping.
Assuming, that "the 12th user" means the user with the ID 12:
In MySQL 8.0+ you can use dense_rank().
SELECT x.rating_index
FROM (SELECT r.user_id,
dense_rank() OVER (ORDER BY sum(r.score) DESC) rating_index
FROM quiz_rashad.rating r
GROUP BY r.user_id) x
WHERE x.user_id = 12;
Edit:
For MySQL 5.7 you have to use subqueries getting the distinct count of total scores greater than or equal the total score for the user with ID 12.
SELECT count(DISTINCT x.score) rating_index
FROM (SELECT r.user_id,
sum(r.score) score
FROM quiz_rashad.rating r
GROUP BY r.user_id) x
WHERE x.score >= (SELECT sum(r.score)
FROM quiz_rashad.rating r
WHERE r.user_id = 12)
We can try using LIMIT with OFFSET here:
SELECT user_id, SUM(score) AS score
FROM quiz_rashad.rating
GROUP BY user_id
ORDER BY score DESC
LIMIT 1 OFFSET 11;
This answer assumes that what you really want here is the record with the twelfth rank. It also assumes that no two users would be tied for the same score.

Getting the sum of column grouped by date

Was wondering if there is a way to get the sum of the stock_case column for items with the same date_of_export ?
Updated with fiddle here and some relevant data:
https://www.db-fiddle.com/f/szC1Ftj3ZGEC24gSYp6ad4/4
The expected output would be this:
This is the query used
SELECT
st.product_code,
st.date_of_export,
st.best_before_date,
st.stock_case,
(
SELECT
SUM(st2.stock_case)
FROM
stock_tracking AS st2
WHERE
st2.product_code IN ('MGN003')
AND MONTH(st2.date_of_export) IN (07)
AND YEAR(st2.date_of_export) IN (2018)
AND st2.stock_case != 0
) AS total
FROM
stock_tracking st
WHERE
product_code IN ('MGN003')
AND MONTH(st.date_of_export) IN (07)
AND YEAR(st.date_of_export) IN (2018)
AND stock_case != 0
and my results
Would like to have a total column like 16, 16, 16, ... , 19, etc
For another case I used a subquery like so
SELECT
d.products_name,
stock_case,
st.date_of_export,
st.best_before_date,
st.product_code,
(SELECT
SUM(st2.stock_case)
FROM
stock_tracking AS st2
WHERE
DATE(st2.date_of_export) = (SELECT
DATE(tmp.last_update)
FROM
(SELECT
date_of_export AS last_update
FROM
stock_tracking
ORDER BY date_of_export DESC
LIMIT 1) AS tmp
WHERE
product_code = 'MGN003')) AS total
FROM
stock_tracking st
LEFT JOIN
products AS p ON p.products_model = st.product_code
LEFT JOIN
products_description AS d ON d.products_id = p.products_id
WHERE
product_code = 'MGN003'
AND d.language_id = 2
AND DATE(st.date_of_export) = (SELECT
DATE(tmp.last_update)
FROM
(SELECT
date_of_export AS last_update
FROM
stock_tracking AS st
ORDER BY date_of_export DESC
LIMIT 1) AS tmp)
with this result:
You can write a subquery to sum(stock_case) by date_of_export, then self join on Date, then you can get your expect result.
SELECT
s.product_name,
s.date_of_export,
s.best_before_date,
s.product_code,
s.stock_case,
t.totle
FROM
stock_tracking s
INNER JOIN
(
SELECT SUM(stock_case) totle,date_of_export dt
FROM stock_tracking
where
product_code = 'MGN003'
AND MONTH(date_of_export) =07
AND YEAR(date_of_export) =2018
AND stock_case != 0
GROUP BY date_of_export
) t on DATE_FORMAT(s.date_of_export, "%d-%m-%Y") = DATE_FORMAT(t.dt, "%d-%m-%Y")
where
s.product_code = 'MGN003'
AND MONTH(s.date_of_export) =07
AND YEAR(s.date_of_export) =2018
AND s.stock_case != 0
sqlfiddle
Without giving you the exact answer: You should think in the direction of:
SELECT SUM(column) FROM table WHERE ... GROUP BY date
or
SELECT SUM(column), DISTINCT date FROM table WHERE ...
So lookup the way GROUP BY and DISTINCT work :-)

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

MYSQL GROUP BY MAX score

I have a table called scores which contains columns
How do I select which id_team is top scorer per game
i m trying with this, but that's not correct result
SELECT MAX( score ) , id_team
FROM scores
GROUP BY `id_game`
LIMIT 0 , 30
You can use a self join to find out the right team id for game a which has max score
SELECT s.*
FROM scores s
JOIN (
SELECT MAX(score) score, id_game
FROM scores
GROUP BY id_game ) ss USING(score ,id_game )
LIMIT 0 , 30
select A.id_game, A.id_team as winning_team
from scores A,
(
select max(score) as max, id_game
from scores
group by id_game
)B
where A.id_game = B.id_game
and A.score = B.max