I have to get the player_id and the game_code of the game the user played the most. For each player list the game_code he played the most (not all games he played)
Rules: player_id is unique, and the player could have played multiple games (I want to find out which game he played the most).
I tried with max but I just got lost in trying out.
Here is the fiddle: http://sqlfiddle.com/#!9/0cf0f/2
I believe you want this
SELECT t.player_id, t.game_code, t.minutes_played
FROM (
SELECT player_id, MAX(minutes_played) as maxi
FROM play_table
WHERE game_code in ('123','124','125','126','129')
GROUP BY player_id
) as m
INNER JOIN play_table as t
ON t.player_id = m.player_id and
t.minutes_played = m.maxi
sqlfiddle demo
The other answer is on the right track, but you need to group by player_id in the subquery, assuming you want all of them:
SELECT m.player_id, pt.game_code, pt.minutes_played
FROM (
SELECT player_id, max(minutes_played) as maxi
FROM play_table
GROUP BY player_id
) as m
INNER JOIN play_table pt
ON m.player_id = pt.player_id
AND pt.minutes_played = m.maxi;
Related
I have a table that roughly looks like the following:
winner_name
loser_name
Person A
Person B
Person A
Person C
Person B
Person A
Person C
Person B
I'm trying to return a table that looks like the following:
player_name
number_wins
number_losses
Person A
2
1
Person B
1
2
Person C
1
1
I can't quite figure out how to get there. I have been able to write a query that returns player_name and either number_wins or number_losses, but not both.
SELECT winner_name AS player_name, COUNT(*) AS number_wins
FROM my_table
GROUP BY player_name
I have looked into using procedures, functions, and subqueries to do this but I haven't found the right solution yet. Any direction would be helpful.
You need to pivot the names into the same column using UNION. Then you can calculate the sum of wins and losses.
SELECT player_name, SUM(win) AS number_wins, SUM(loss) AS number_losses)
FROM (
SELECT winner_name AS player_name, 1 AS win, 0 AS loss
FROM my_table
UNION ALL
SELECT loser_name AS player_name, 0 AS win, 1 AS loss
FROM my_table
) AS x
GROUP BY player_name
Since each aggregate statistic is for a different group (one for winner_name, the other for loser_name), they can't be calculated in the same query, but each query can be run separately and then combined with a JOIN. Simply take each query:
SELECT winner_name AS player, COUNT(loser_name) AS wins
FROM games
GROUP BY winner_name
;
SELECT loser_name AS player, COUNT(winner) AS losses
FROM games
GROUP BY loser_name
;
and join on the common attribute, the player name:
SELECT gw.player, gw.wins, gl.losses
FROM (
SELECT winner_name AS player, COUNT(loser_name) AS wins
FROM games
GROUP BY winner_name
) AS gw
JOIN (
SELECT loser_name AS player, COUNT(winner_name) AS losses
FROM games
GROUP BY loser_name
) AS gl
ON gl.player = gw.player
;
Whether using unions or joins, each distinct group that is the basis for aggregate statistics will require a separate sub-select.
I need to count the amount of games a player has played by counting the number of times his player ID appears on another table, here is the code I've been playing with:
SELECT players.playerID, players.fName, players.lName, matches.playerID, COUNT(matches.playerID) AS 'gamesPlayed'
FROM players
INNER JOIN matches
ON matches.playerID = players.playerID
WHERE players.playerID=matches.playerID
ORDER BY gamesPlayed"
Currently there is 2 players having played 2 matches.
The current code returns 1 player having played 4 matches.
I am trying to get the COUNT(matches.playerID) to return only matches where the players.playerID = matches.playerID.
Any help is much appreciated!
You need to GROUP BY:
SELECT p.playerID, p.fName, p.lName, COUNT(*) AS gamesPlayed
FROM players p INNER JOIN matches m
ON p.playerID = m.playerID
GROUP BY p.playerID, p.fName, p.lName
ORDER BY gamesPlayed
If you want even players who have played zero games, then:
SELECT p.playerID, p.fName, p.lName, COUNT(m.playerID) AS gamesPlayed
FROM players p LEFT JOIN matches m
ON p.playerID = m.playerID
GROUP BY p.playerID, p.fName, p.lName
ORDER BY gamesPlayed
The reason I use COUNT(m.playerID) instead of COUNT(*) in the above is because COUNT(*) will always be at least one in this instance, while COUNT(m.playerID) can be zero if the only matched value is NULL.
At first place: your query lacks GROUP BY, at second - please check what argument COUNT accepts (in this query it's no different from COUNT(*)) – zerkms
I'm struggling a little with a query I'm trying to build. For a game I want to display the top 10 of scores.
My table looks like this:
player = id, playername, username
score = id, track, car, bestscore, totalscore, player_id (foreign key to player.id)
For the top10 I want to show the playername, the total score, the car and the track.
The current query I have is:
SELECT p.playername, MAX(s.totalscore) totalscore, s.car, s.track
FROM player p
INNER JOIN score s on p.id = s.player_id
GROUP BY p.playername
ORDER BY MAX(s.totalscore) DESC
LIMIT 10
This seems to work fine, except for one problem. If a user has a score of 50 on track 1 with car 1, and then puts a score of 60 on track 1 with car 2, I see car 1 on the query. It does not seem to get the according car of the top score if this user.
I hope it makes sense what I just told.
Thanks in advance!
EDIT:
SELECT p.playername, MAX(s.totalscore) as totalscore, s.car, s.track
FROM (SELECT * FROM score ORDER BY totalscore DESC) s
INNER JOIN player p ON s.player_id = p.id
GROUP BY p.playername
ORDER BY MAX(s.totalscore) DESC
LIMIT 10
This query seems to do the trick. I've been trying around and the result-set is exactly what I mean. Is it any good though? I'm not good at SQL and just because it works doesn't always mean it's good, does it?
When you have a non-aggregated field as part of an aggregated query that isn't in your group by, and has a many to one relationship with the relation on which you are grouping, MySQL gives no guarantee what it will return.
This query would throw an error in another RDBMS. If you care about the top score by (person,car) tuple, just add it to the group by. However, if you want each player to have a max score, regardless of what car was used, you'll need a subquery or a self join.
One way to do it:
SELECT p.playername, s1.totalscore , s1.car, s1.track
FROM player p
INNER JOIN
score s1 on p.id = s1.player_id
WHERE s1.totalscore = ( SELECT MAX(totalscore) FROM score s2 WHERE s2.player_id=s1.player_id)
ORDER BY s1.totalscore DESC
LIMIT 10
You use "Group By" on playername so the other columns will group in "what mysql desides" manner. If you want to get the cars you should add - group by car.
SELECT p.playername, MAX(s.totalscore) totalscore, s.car, s.track
FROM player p
INNER JOIN score s on p.id = s.player_id
GROUP BY p.playername, s.car //added car
ORDER BY s.totalscore DESC
LIMIT 10
I am in need of your help:
I have a set of relational tables set up for Users, Games and Results and I am trying to calculate each users Win Percentage.
Thanks to a lot of browsing I have discovered the following method:
SELECT Winner, (COUNT(Winner) * games.TotalPlayed) AS PercentWon
FROM Results
JOIN (
SELECT 100/COUNT(*) AS TotalPlayed
FROM games
where Player_1 = 'John' OR Player_2 = 'John'
) AS games
where Winner == 'John'
GROUP BY Winner
ORDER BY PercentWon DESC;
This works perfectly for getting Johns % but I want it to scan the whole Results table and print values for everyone. However, I am not allowed use:
SELECT Winner, (COUNT(Winner) * games.TotalPlayed) AS PercentWon
FROM Results
JOIN (
SELECT 100/COUNT(*) AS TotalPlayed
FROM games
where Player_1 = Winner OR Player_2 = Winner
) AS games
where Winner != 'Draw'
GROUP BY Winner
ORDER BY PercentWon DESC;
as Winner is not defined. How can I get the value of Winner passed to the subquery as it is being performed?
I've finally come up with something that'll work for you. It was tricky because the player can be in one of two fields in the games table.
SELECT player, (COALESCE(totalWon, 0) / count(*) * 100) as PercentWon
FROM ((SELECT DISTINCT Player_1 as player FROM games) UNION (SELECT DISTINCT Player_2 as player FROM games)) players
INNER JOIN games on (games.Player_1 = player or games.Player_2=player)
LEFT JOIN
(
SELECT Winner, COUNT(Winner) as totalWon
FROM Results
WHERE Winner != 'Draw'
GROUP BY Winner
) as winners
ON winners.Winner = player
GROUP BY player
ORDER BY PercentWon DESC;
The UNION in the FROM clause is building a user list that I can use to join games (to find the total number of games per player) and winners (to find the number of wins per player).
COALESCE is used for the case when a player has not won any games. Since we are joining table, this allows us to default 0 instead of NULL when there are no matches.
Here's an sqlfiddle based on my assumptions about your schema:
http://sqlfiddle.com/#!2/d762c/1/0
i have the following tables.
i want to fetch all the player statistics record from the given tables, the records of individual player includes.
Player Name
Position
Total Number of games played
Number of goals scored
Total number of assist for goals.
Total Points (total goals + total assist = total points).
after trying i came up with this query
SELECT SQL_CALC_FOUND_ROWS
CONCAT(u.first_name, ' ', u.last_name) as player_name,
p.position,
COUNT(g.id)
FROM
gce_player p
LEFT JOIN
gce_user u ON(u.id = p.user_id)
LEFT JOIN
gce_game_team_lineup gtl ON(gtl.player_id = p.id)
LEFT JOIN
gce_game_team gt ON(gt.id = gtl.game_team_id)
LEFT JOIN
gce_game_goal gg ON(gg.player_id = p.id)
LEFT JOIN
gce_game g ON(g.id = gt.game_id)
GROUP BY p.id
ORDER BY p.id asc
the above query returns me proper record till total number of games played, i am facing issue fetching the proper records after this, ill appreciate any kind of help on this.
here is the link to sqlfiddle if you want to look at the schema, i have added some test data too.
thank you.
UPDATE :
here are few of the rules to remember.
Number of goals scored = total number of goals scored by a player. for example if in gce_game_goal table there are 10 rows which have
the value of player_id as 4 it means the player have scored 10 goals
and i need to fetch this record for individual player, and
likewise if there are 7 rows in which player_id have value of 3 this
means player with id 3 have scored 7 goals and likewise.
Total number of assist for goals = total number of assist given to a goalie by a player (assist is like a pass in football). i need to
calculate total number of assist or pass that was done by a user.
for each goal there will be two assist, and each assist are players
who pass the ball to a golaie. i want to count the number of passes
or assist given by a player. for example if in gce_game_goal
table there are 8 rows or records that have the value of 3 in either
assis1_id or assist2_id column, this means player with id 3 have
scored 8 assist in total
.
kindly let me know if you still have any doubts/question, ill try to improve my question
Thanks
The problem that you are facing is caused by aggregating along multiple different dimensions of the data (say by game and by goal). This results in a cross product for each player.
A fairly general solution is to do aggregations in the from clause, along each dimension. Each variable (or perhaps a few variables) comes from a different aggregation:
select u.last_name, u.first_name, p.position,
pg.goals, pg.assists, (pg.goals + pg.assists) as TotalPoints
from gce_player p join
gce_user u
on p.user_id = u.id left outer join
(select player_id, SUM(goal) as goals, SUM(assist) as assists
from ((select player_id, 1 as goal, 0 as assist
from gce_game_goal
) union all
(select assist1_id, 0 as goal, 1 as assist
from gce_game_goal
) union all
(select assist2_id, 0 as goal, 1 as assist
from gce_game_goal
)
) t
group by player_id
) pg
on pg.player_id = p.id left outer join
(select gtl.player_id, count(*) as NumTeams
from gce_game_team_lineup gtl join
gce_game_team gt
on gtl.id = gt.team_id
) g
on g.player_id = p.id
Try this
SELECT
CONCAT(u.first_name, ' ', u.last_name) as player_name,
count(g.id) as Goals,
(select
count(*)
from
gce_game_goal
where
assist1_id = p.player_id)
+(select
count(*)
from
gce_game_goal
where
assist2_id = p.player_id) as Assists,
count(g.id)
+ (select
count(*)
from
gce_game_goal
where
assist1_id = p.player_id)
+ (select
count(*)
from
gce_game_goal
where
assist2_id = p.player_id) as Total
FROM
gce_player as p
LEFT JOIN
gce_game_goal as g ON p.id = g.player_id
LEFT JOIN
gce_user u ON(u.id =p.user_id)
GROUP BY p.player_id