I want to select the average of the high score for 2-3 players but im not sure how to go about this.
Table Match has (id, player, score)
I would like to get the maximum score for each specified player (by id) and then calculate the average of these returned scores.
Any help would be appreciated
CREATE TABLE Match(Id integer PRIMARY KEY, score integer);
/* Create few records in this table */
INSERT INTO Match VALUES(1,'10');
INSERT INTO Match VALUES(2,'20');
INSERT INTO Match VALUES(3,'60');
INSERT INTO Match VALUES(4,'100');
INSERT INTO Match VALUES(5,'80');
COMMIT;
select m.*,
(select sum(score)
from (select score
from Match s
where s.id = s.id
order by score desc
limit 3
) s2
) as summax3
from Match m
The following query is going to return the highest score of each player:
SELECT *
FROM
(
SELECT `match`.id, `match`.score
FROM `match`
ORDER BY score DESC
LIMIT 3
) AS high_scores
GROUP BY id
ORDER BY score DESC
And for getting the average:
SELECT AVG(score) AS average
FROM
(
SELECT `match`.id, `match`.score
FROM `match`
ORDER BY score DESC
LIMIT 3
) AS high_scores
Related
My sql statement is as follows:
SELECT course_id FROM (
(SELECT COUNT(course_id) AS count FROM takes GROUP BY course_id) AS result)
WHERE count IN (SELECT MAX(count) FROM result)
How can I use temporary tables twice?For example,the table "result" here.
If you simply want to obtain the course_id which has the maximum number of takes, then you can order the subquery by the count and limit the result set to one record.
SELECT course_id, COUNT(course_id) AS count
FROM takes
GROUP BY course_id
ORDER BY COUNT(course_id) DESC
LIMIT 1
If you also want to obtain all course id values, in the event that there be a tie for the maximum number of takes, then you can try the following slightly more complicated query:
SELECT result.course_id
FROM
(
SELECT course_id, COUNT(course_id) AS count
FROM takes
GROUP BY course_id
) AS result
WHERE result.count = (
SELECT COUNT(*)
FROM takes
GROUP BY course_id
ORDER BY COUNT(*) DESC
LIMIT 1
)
I have table in MySQL DB which contains among other things two fields user_id and score. This table is kind of log table so there can be multiple rows for one user_id with different scores. How can I get only top 10 users with highest score from this table?
SELECT DISTINCT user_id
FROM your_table
ORDER BY score DESC
LIMIT 10
EDIT:
SELECT DISTINCT *
FROM your_table
WHERE (user_id, score) IN (SELECT user_id, MAX(score) AS score
FROM your_table
GROUP BY user_id)
ORDER BY score DESC
LIMIT 10
SqlFiddleDemo
This is basic and you should put more effort; here is atemplate you can use -
SELECT TOP 10 distinct *
FROM people
WHERE names='SMITH'
ORDER BY names asc
I have a table which has a int column representing for scores of student. I want to select the 2nd highest score if there does exists for 2nd highest score, and if not, return null. Wondering how to implement in SQL.
I am using MySQL/SQL Workbench.
This query would return the second highest value if present or-else NULL
SELECT MAX(score)
FROM table_name
WHERE score<>(
SELECT MAX(score)
FROM table_name);
Please try executing following sql query for retrieving 2nd highest score
SELECT score from table order by score desc limit 1,1
The above query will return 2nd highest score if it exists or NULL if it the record does not exists
When there is top 2 highest scores then the second one will be displayed
other wise ie: if it has single maximum value overall the table then it displays null..
select top 1 case when row_number() over (order by tbl.score asc) =2 then a else null end ,row_number() over (order by tbl.score asc) as ranks from (
select top 2 score from table group by score order by 1 desc
)tbl
order by 1 desc
I have selected top two records of desc then taking second record..
If it is not present then it will displays null
Try following query
SELECT max(score) FROM table WHERE score NOT IN (SELECT max(score) FROM table);
OR
SELECT max(score) FROM table WHERE score < (SELECT max(score) FROM table);
I was thinking about this on how to display the nth highest value not only the 2nd. We could use the min code instead of the max.
Select * from employee where salary= (Select min(salary) from (select * from employee order by salary desc limit 2) as MyTop);
this can modified for any nth highest value wanted by only changing the desc limit to the "nth" needed.
I am having trouble writing a query for the following problem. I have tried some existing queries but cannot get the results I need.
I have a results table like this:
userid score timestamp
1 50 5000
1 100 5000
1 400 5000
1 500 5000
2 100 5000
3 1000 4000
The expected output of the query is like this:
userid score
3 1000
1 1000
2 100
I want to select a top list where I have n best scores summed for each user and if there is a draw the user with the lowest timestamp is highest. I really tried to look at all old posts but could not find one that helped me.
Here is what I have tried:
SELECT sum(score) FROM (
SELECT score
FROM results
WHERE userid=1 ORDER BY score DESC LIMIT 3
) as subquery
This gives me the results for one user, but I would like to have one query that fetches all in order.
This is a pretty typical greatest-n-per-group problem. When I see those, I usually use a correlated subquery like this:
SELECT *
FROM myTable m
WHERE(
SELECT COUNT(*)
FROM myTable mT
WHERE mT.userId = m.userId AND mT.score >= m.score) <= 3;
This is not the whole solution, as it only gives you the top three scores for each user in its own row. To get the total, you can use SUM() wrapped around that subquery like this:
SELECT userId, SUM(score) AS totalScore
FROM(
SELECT userId, score
FROM myTable m
WHERE(
SELECT COUNT(*)
FROM myTable mT
WHERE mT.userId = m.userId AND mT.score >= m.score) <= 3) tmp
GROUP BY userId;
Here is an SQL Fiddle example.
EDIT
Regarding the ordering (which I forgot the first time through), you can just order by totalScore in descending order, and then by MIN(timestamp) in ascending order so that users with the lowest timestamp appears first in the list. Here is the updated query:
SELECT userId, SUM(score) AS totalScore
FROM(
SELECT userId, score, timeCol
FROM myTable m
WHERE(
SELECT COUNT(*)
FROM myTable mT
WHERE mT.userId = m.userId AND mT.score >= m.score) <= 3) tmp
GROUP BY userId
ORDER BY totalScore DESC, MIN(timeCol) ASC;
and here is an updated Fiddle link.
EDIT 2
As JPW pointed out in the comments, this query will not work if the user has the same score for multiple questions. To settle this, you can add an additional condition inside the subquery to order the users three rows by timestamp as well, like this:
SELECT userId, SUM(score) AS totalScore
FROM(
SELECT userId, score, timeCol
FROM myTable m
WHERE(
SELECT COUNT(*)
FROM myTable mT
WHERE mT.userId = m.userId AND mT.score >= m.score
AND mT.timeCol <= m.timeCol) <= 3) tmp
GROUP BY userId
ORDER BY totalScore DESC, MIN(timeCol) ASC;
I am still working on a solution to find out how to handle the scenario where the userid, score, and timestamp are all the same. In that case, you will have to find another tiebreaker. Perhaps you have a primary key column, and you can choose to take a higher/lower primary key?
Query for selecting top three scores from table.
SELECT score FROM result
GROUP BY id
ORDER BY score DESC
LIMIT 3;
Can you please try this?
SELECT score FROM result GROUP BY id ORDER BY score DESC, timestamp ASC LIMIT 3;
if 2 users have same score then it will set order depends on time.
You can use a subquery
SELECT r.userid,
( SELECT sum(r2.score)
FROM results r2
WHERE r2.userid = r.userid
ORDER BY score DESC
LIMIT 3
) as sub
FROM result r
GROUP BY r.userid
ORDER BY sub desc
You should do it like this
SELECT SUM(score) as total, min(timestamp) as first, userid FROM scores
GROUP BY userid
ORDER BY total DESC, first ASC
This is way more efficient than sub queries. If you want to extract more fields than userid, then you need to add them to the group by.
This will of cause not limit the number of scores pr user, which indeed seems to require a subquery to solve.
I have the following tables:
player_records
int id (pk)
int player_id (fk)
int round_id (fk)
int kills
players
int id (pk)
varchar name
rounds
int id (pk)
int duration // round duration in seconds
I need to select kills/hour (SUM(kills)/SUM(duration/60/60)) ratio for each player from the last 10 rounds they've participated, provided not every player takes part in a round.
All similar questions that I've found point to this article, but I haven't been able to apply its tricks to my needs above as I have to limit the records to 10 before grouping.
To further illustrate it, this is how I'd be doing if I needed just a single player:
SELECT SUM(t1.kills)/SUM(t1.duration)*60*60 kills_hour_last_10
FROM (
SELECT records.kills, rounds.duration
FROM records
JOIN rounds ON rounds.id = records.round_id
WHERE records.player_id = 1
ORDER BY records.id DESC
LIMIT 10
) t1;
Updated with fiddle (Those 3 queries represent the expected results for each player. All I need is to know how to get all of them in the same query).
You can use a rank query mysql does not have window functions for this type of results to get n records per group
SELECT t.player_id,
SUM(t.kills)/SUM(t.duration)*60*60 kills_hour_last_10
FROM (
SELECT *,
#r:= CASE WHEN #g = player_id THEN #r + 1 ELSE 1 END rownum,
#g:= player_id
FROM (
SELECT r.player_id,r.id,r.kills, rs.duration
FROM records r
JOIN rounds rs ON rs.id = r.round_id
ORDER BY r.player_id ASC,r.id DESC
) t1
CROSS JOIN (SELECT #g:=NULL,#r:=NULL) t2
) t
WHERE rownum <= 10
GROUP BY t.player_id
Fiddle Demo
Above query will give ranks to the record which belongs to same player_id group and in parent query you can limit records to 10 for each player_id and the perform your aggregation logic note that ORDER BY r.player_id,r.id DESC is important to order results by player and then its records in descending manner,if you need player names then join players in parent query