Mysql order based on sum result - mysql

I have a Mysql table with users playing as double partners in a tennis tournament and also a table with rankings in which every player has a ranking score in doubles matches.
Tournaments_registrations_doubles
id
player1_id
player2_id
1
32
25
2
25
28
3
143
83
Rankings_doubles
id
player_id
points
1
25
127
2
19
83
3
32
97
4
83
41
I am trying to build an SQL query that will get the ids of the Tournaments_registrations_doubles table in descending order based on the sum of the ranking points of each player group. So player_1 and player_2 who's sum of point in rankings table is highest should come first, and so on. Not all players are registered in the ranking table.
Any ideas on how to implement this?

Join the tournament table to the doubles table twice, once for each of the two player columns. Then order the result set descending by the sum of points.
SELECT t.id, t.player1_id, t.player2_id,
COALESCE(r1.points, 0) + COALESCE(r2.points, 0) AS total
FROM Tournaments_registrations_doubles t
LEFT JOIN Rankings_doubles r1 ON r1.player_id = t.player1_id
LEFT JOIN Rankings_doubles r2 ON r2.player_id = t.player2_id
ORDER BY COALESCE(r1.points, 0) + COALESCE(r2.points, 0) DESC;
Notice that we use left joins here, so that we may treat missing points as zero when computing the totals.

Related

Average from joined tables

I have a query:
SELECT p.NAME, r.DATE, c.NAME, SUM(hs.result), SUM(h.par), (SUM(hs.result) - SUM(h.par)) AS "Score"
FROM hole_scores hs
JOIN players p ON hs.player_id = p.id
JOIN rounds r ON r.id = hs.session_id
JOIN holes h ON h.id = hs.hole_id
JOIN courses c ON c.id = r.course_id
GROUP BY p.NAME, r.id
ORDER BY Score ASC
The query gives me this result (first rows):
NAME DATE NAME SUM(hs.result) SUM(h.par) Score
Player 1 29.7.2014 Course 1 50 57 -7
Player 2 7.6.2014 Course 2 48 54 -6
Player 1 22.5.2014 Course 1 51 57 -6
Player 3 6.6.2014 Course 1 52 57 -5
Player 1 19.8.2013 Course 1 53 57 -4
Player 4 1.9.2011 Course 1 56 59 -3
Player 5 15.10.2011 Course 1 56 59 -3
Player 4 2.8.2013 Course 1 54 57 -3
Player 1 3.6.2014 Course 1 54 57 -3
Player 6 8.7.2014 Course 1 54 57 -3
Player 4 16.7.2014 Course 1 54 57 -3
Player 1 21.4.2015 Course 1 53 56 -3
Player 2 23.6.2012 Course 2 52 54 -2
How would I get average of each player scores?
Please try the following...
SELECT players.id AS player_id,
players.name AS player_name,
AVG( Score ) AS avg_score
FROM ( SELECT hole_scores.player_id AS player_id,
( SUM( hole_scores.result ) - SUM( holes.par ) ) AS Score
FROM hole_scores
JOIN holes ON holes.id = hole_scores.hole_id
JOIN rounds ON rounds.id = hole_scores.session_id
GROUP BY hole_scores.player_id,
rounds.id
) AS scoreFinder
JOIN players ON players.id = scoreFinder.player_id
GROUP BY players.id
ORDER BY player_name,
player_id;
This statement uses a subquery based on a reduced version of your supplied statement to find the scores for each player for each round.
Note that normally name can not be safely assumed to be unique as it is normally possible, even if it is not normally the case, that two players can have the same name. As such I have chosen the id value to uniquely identify each player. Since this value can be found in hole_scores.player_id there is no need to join with players at this stage.
It then performs an INNER JOIN between the subquery's results and players so that the name of each player may be included in the results. I chose to join with players at this stage rather than in the subquery as the results of the subquery will have only one record for each player to join to rather than potentially many for each player in the subquery's source dataset. I hope that this will make the statement slightly more efficient.
The statement then groups the joined dataset's records by the unique identifier for each player, and returns the id and name values for each player along with the average value of their Score at the end of each round.
If you have any questions or comments, then please feel free to post a Comment accordingly.
If you want the average, I think you can do:
SELECT p.NAME, (SUM(hs.result) - SUM(h.par))/COUNT(*) AS "Score"
FROM hole_scores hs JOIN
players p
ON hs.player_id = p.id JOIN
rounds r
ON r.id = hs.session_id JOIN
holes h
ON h.id = hs.hole_id JOIN
courses c
ON c.id = r.course_id
GROUP BY p.NAME
ORDER BY Score ASC

select top 5 scores for each team [duplicate]

This question already has answers here:
Using LIMIT within GROUP BY to get N results per group?
(14 answers)
Closed 5 years ago.
This is different from the one marked as a double, I want to sum up top 5 for each team. The double post takes out for each of the results in separate rows.
I'm using this question now but it seems that SQL is randomly returning 5 of for exasmple 10 rows and sum up, not the top 5. Anyone has some input for me?
select team, sum(length) as totalScore
from
(SELECT t.*,
#num_in_group:=case when #team!=team then #num_in_group:=0 else #num_in_group:=#num_in_group+1 end as num_in_group,
#team:=team as t
FROM reg_catches t, (select #team:=-1, #num_in_group:=0) init
ORDER BY team asc) sub
WHERE sub.num_in_group<=4 and competition = 16 and team = 25
GROUP BY team
ORDER BY totalScore DESC;
I'm struggeling on a SQL question that I can't get my head around. My result-table looks like below, I'm trying to sum up the top 5 result for each team and limit the output to the top 3 highest ranked teams. Everything was working as expected until I added my last score in the result-table. The output of my SQL now is randomly for team 25. I've expected that to be 520..
team length competition
----------------------
26 70 16
25 70 16
25 95 16
25 98 16
25 100 16
25 100 16
25 100 16
25 122 16
Output:
team totalScore
---- -----------
25 122
26 70
Wanted output:
team totalScore
---- -----------
25 522
26 70
SELECT team, SUM(length) AS totalScore
FROM(
SELECT team, length
FROM table_result m
WHERE competition = 16 and (
SELECT COUNT(*)
FROM table_result mT
WHERE mT.team = m.team AND mT.length >= m.length
) <= 5) tmp
GROUP BY team
ORDER BY totalScore DESC Limit 3
Anyone has any ideas for me?
select team, sum(length)
from
(SELECT t.*,
#num_in_group:=case when #team!=team then #num_in_group:=0 else #num_in_group:=#num_in_group+1 end as num_in_group,
#team:=team as t
FROM test.table_result t, (select #team:=-1, #num_in_group:=0) init
ORDER BY team, length desc) sub
WHERE sub.num_in_group<=4
GROUP BY team
You should use a window function to accomplish this. Here's an example query:
SELECT team, SUM(length) AS totalScore FROM
(SELECT team,
length,
row_number() OVER (PARTITION BY team ORDER BY length desc) AS rowNumber
FROM table_result) tmp
WHERE rowNumber <= 5
AND competition = 16
GROUP BY team
ORDER BY totalScore DESC
LIMIT 3;
This query has two parts.
The inner query uses the row_number() window function to give every row an extra column that indicates its rank. PARTITION BY team says that the rank should be kept separately for each team, so that you end up being able to select the top n scores for every team.
The outer query uses a GROUP BY on the result of the inner query to take the SUM, per team, of all of the scores whose row number is less than or equal to 5 - in other words, the top 5 scores.

SQL query to repeat each row n times and add to it, data from another table

I have one SQL query with result table having a list of 700 userids and the corresponding gameids (games played by the user; there are totally 1000 games).
One user might have played more than one games and one gameid may be associated with more than one userid. I have another table in the database that has the list of all gameids and their respective attributes.
I want my final result table to be like: column 1 with all 700 userids (each repeated as many times as the number of gameids associated with the user) and column 2 with the corresponding gameids AND other gameids from the gameid table. These other gameids against each userid should be different from the ones already placed against the userid.
table1
Userid Gameid
1 3
1 4
2 63
2 76
6 99
6 63
table2
Gameid gamename
1 GTA
2 DOTA
1000 xyz
result table
Userid Gameid Gamename
1 3 AOE
1 4 Roadrash
1 1 GTA
1 2 DOTA
1 5 qbc
so on up to
1 1000 xyz
similarly for all userids from table1.
Result table has each user id repeated 1000 times and the top n gameids against each userid are the ones from table1(games the particular users have played) and the rest of the gameids are from the 1000 from table 2(therefore each user is mapped against all the gameids with the top ones being the games they've played).
The idea of the data set up is to include a column in the end of the result table that has binary values (1 -> user has played the game, 0 -> user has not played the game). This table is to be used for machine learning.
Build the result table as a union of the games played by users and the games not played by users like so:
select UserId, GameId, GameName, Played
from (
-- games played
select usr.UserId, gme.GameId, gme.GameName, 1 as Played
from USERS usr
inner join GAMES gme on usr.GameId = gme.GameId
union
-- games not played
select usr.UserId, gme.GameId, gme.GameName, 0 as played
from USERS usr, GAMES gme
where gme.GameId not in (
select usr2.GameId
from USERS usr2
where usr2.UserId = usr.UserId
)
)
order by Userid, Played desc, Gameid
The outer select is used to order the results set such that games played are provided first.

Complex MySQL statement to list fishing standings?

I'm trying to make a standings chart using multiple tables. One keeps tracks of meetings attended to, each meeting counting as 5 points and the other table keeps track of results of tournaments. This is a fishing club site.
I have the following so far and can show the meeting points in order but the tournament results separate from that. I'd like to find a single albeit complex SQL statement to list out current standings.
I need to show the angler name which I can grab separate from a different table, then each month's 5 points listed along with the tournament result amount from the results table, these are all added up to finally list the total from all tournaments and meetings.
SELECT aid, sum(here*5) as total
FROM rollcall GROUP BY aid ORDER BY total DESC
SELECT aid, weight, weight-penalty as fweight
FROM `results` where tid=2 order by fweight desc
So an example is:
place angler JAN FEB MARCH ... Total Points
1 name1 5 50 5 45 0 38 143
2 name2 5 49 5 47 5 31 142
...
Is that clear at all?
What if you build your query something like this?
SELECT aid,
sum(SELECT count(1) from meetings WHERE MONTH(columndatetime) = 1 * 5) AS JAN,
sum(SELECT count(1) from meetings WHERE MONTH(columndatetime) = 2 * 5) AS FEB,
/
-- add same logic to the rest of the months
/
sum(SELECT count(1) from meetings WHERE YEAR(columndatetime) = 2013 * 5) as total
FROM rollcall GROUP BY aid ORDER BY total DESC
Where columndatetime is the name of your column that has the date and time for the meetings etc...
The last one takes all for the year.
Could this help you out?

Finding the maximum of various sum of values in mysql

I have a table with values as shown
Player || Match || Score
A 1 72
B 1 55
A 2 100
C 1 90
B 2 175
I wish to obtain the player name who has scored maximum runs(sum of his scores in all the matches) in this table.
How can this be done in efficient way in mysql
Thanks
Unverified:
select Player
from myTable
group by Player
order by sum(score) desc
limit 1
$query = "SELECT player,MAX(SUM(Score)) FROM table_name GROUP BY player";