COUNT() rows value in an INNER JOIN - mysql

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

Related

top 10 scorers by season

How I can get top 10 scorers by seasons.
So it shows last season top 10 scorers...
I've tryed left join into table, but it goes broken showing 2 player and counts all goals to first player.
My sqlfiddle:
http://sqlfiddle.com/#!9/b5d0a78/1
You got it almost right.
You want to group match_goals by player ID (match_player_id), but then you should not select goal_minute or any other per goal data.
After grouping by player, then you can create a column for COUNT(match_player_id) this will give you the number of goals, you can also use this column to order the results.
Your joins and conditions are correct I think.
EDIT
I think your schema needs a few tweaks: check this http://sqlfiddle.com/#!9/f5a75b/2
Basically create direct relations in the match_players and match_goals to the other tables.
I think the query you want looks like this:
SELECT p.*, count(*) as num_goals
FROM match_goals g INNER JOIN
match_players p
ON g.match_player_id = p.id INNER JOIN
matches m
ON m.id = p.match_id
WHERE p.is_deleted = 0 AND
g.is_own_goal = 0 AND
m.seasion_id = <last season id>
GROUP BY p.id
ORDER BY num_goals DESC
LIMIT 10;
Note that the teams table is not needed. The SELECT p.* is allowed because p.id (the GROUP BY key) is unique.

Mysql: Count wins but only once per opponent

I'm looking for help using sum() in my SQL query:
Task: Count tournament wins of all players. (one number per player) (battles.result = 1 means Player1 wins)
SELECT members.id, members.name,
(
SELECT SUM(battles.result = 1)
FROM battles
WHERE members.id = battles.player1 AND battles.result=1 order by battles.gametime
( as wins,
FROM members
Next: Only count ONE result per two players.
So if there are multiple results of two players, count only the first result (first gametime).
I've already tried using order by battles.player2, but i guess there is a much better solution?
You can easily get the result by doing a join and aggregation instead. Try:
SELECT A.id, A.name, SUM(IFNULL(B.result,0)) wons
FROM members A LEFT JOIN battles B
ON A.id=B.player1
GROUP BY A.id, A.name;

Determine winner of games and joining with table of names

I have two tables, one called players, one called matches.
The players table contains 2 columns: id, name
The matches table contains 5 columns: player1, player2, goalsforplayer1, goalsforplayer2, matchid
Looking for the right query to get the names (not player id) and the result of matches, ideally comparing the goalsforplayer1 and goalsforplayer2 to get either a winner or a draw in each match. Essentially making a list of results.
Is something like this possible using a mysql query?
You should use two inner join on players
select
b.name as nameplayer1
, c.name as nameplayer2
, a.goalsforplayer1
, a.goalsforplayer2
, a.matchid
from matches as a
inner join players as b on a.player1 = b.id
inner join players as c on a.player2 = c.id
This should be what you're looking for (To get a list of players, and their total match results), and should guide you in the correct direction:
SELECT p.*,
(COUNT(CASE WHEN m1.goalsforplayer1 > m1.goalsforplayer2 THEN 1 ELSE NULL END) +
(COUNT(CASE WHEN m2.goalsforplayer2 > m2.goalsforplayer1 THEN 1 ELSE NULL END)
) AS wins
FROM players p
INNER JOIN matches m1 ON p.id = m1.player1
INNER JOIN matches m2 ON p.id = m2.player2
GROUP BY p.id
Join on the matches table, and group by the ID. Use aggregation functions (COUNT here), to get the total number of matches that a player has won. If you want draws, simply modify the queries.
If you're looking for simple results (With players from each side), then use this:
SELECT p1.name AS player1, p2.name AS player2, m.goalsforplayer1, m.goalsforplayer2, m.matchid
FROM matches m
INNER JOIN players p1 ON p1.id = m.player1
INNER JOIN players p2 ON p2.id = m.player2

psql table querying

I have 3 tables, players, matches, wins. I want to make a query that retrieves back the player id, the name, the amount of matches he played and how many wins he got.
the matches table keeps track of the round it's in, the players who take part (p_one_id and p_two_id) while the wins table keeps track of the match id, to see who he won against, and the player id.
if I do
SELECT players.id, players.name, COUNT(matches.*) as matches FROM players, matches WERE matches.p_one_id = players.id GROUP BY players.id
It works fine, at least from my basic tests ( but that doesn t also check for wins) but if I do
SELECT players.id, players.name, COUNT(matches.*) as matches, COUNT(wins.*) AS wins FROM players, matches, wins WERE matches.p_one_id = players.id AND wins.p_id = players.id GROUP BY players.id
I get nothing, one reason is that there's no wins, but then I d only get the guys who won, I can t make a sub query either, since I can't use the player id inside of the subquery, at least not from my knowledge). Anyone know what query I'd need for my result?
I would suggest using a LEFT JOIN instead of the cross join / where clause option. You may also wish to count the matches where the player was "player 2". Something along the lines of:
SELECT
p.id,
p.name,
count(m1.*) + count(m2.*) as matches,
count(w.*) as wins
FROM players p
LEFT JOIN matches m1
ON m.p_one_id = p.id
LEFT JOIN matches m2
on m.p_two_id = p.id
LEFT JOIN wins w
ON w.p_id = p.id
GROUP BY p.id, p.name
User outer joins. The join syntax you're using is eliminating players unless they have both wins and matches.
SELECT players.id, players.name,
COUNT(matches.p_one_id) as matches,
COUNT(wins.p_id) AS wins
FROM players
LEFT JOIN matches
on matches.p_one_id = players.id
LEFT JOIN wins
on wins.p_id = players.id
GROUP BY players.i, players.name
This will return all players, matches, and wins.

calculating player statistics from database

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