开发者

Mysql join counting rows from another table

开发者 https://www.devze.com 2023-03-06 11:10 出处:网络
I\'m having trouble getting the count of rows from a specific table on two separate conditions for rows from a main table :

I'm having trouble getting the count of rows from a specific table on two separate conditions for rows from a main table :

Mainly, I've got a table for players, with simple 开发者_如何学JAVAinformations, like playername and id. I've got also a table with action, where each player is listed with the type of the action (goal or assist). I want to get all players with a column counting their goals, and another counting their assists. Of course, I want the lazy players, whom haven't score any goals, or made any assists.

For now I came up with this request, but it only gives me the best players, whereas i want all players. Please light my mind ;)

SELECT
  `p`.`playername`, 
  COUNT(`a1`.`actionid`) AS `goals`, 
  COUNT(`a2`.`actionid`) AS `assists`

FROM `Player` AS `p`

LEFT JOIN `Actions` AS `a1` 
ON `a1`.`id` = `p`.`id`

LEFT JOIN `Actions` AS `a2` 
ON `a2`.`id` = `p`.`id`

WHERE `a1`.`type` = 'goal'
  AND `a2`.`type` = 'assist'

GROUP BY  
  `a1`.`userId`,  
  `a2`.`userId` 

LIMIT 0 , 30


I noticed in your query that you're joining your actions table on a condition which references a table aliased as u of which you don't have any table assigned. So, I think your query is probably throwing a MySQL error. Also, in your join conditions you are referencing the Actions table's id field, which I would expect to be, under normal convention, a primary auto-increment key. You may be using it as the player id, I'm unsure, but to be more verbose I changed it to read player_id so you and other would know exactly what was going on in the query below. Under the assumption that you edited your query to be "easier to read" in the SO editor and didn't test it, I tweaked it to what I thought would be more accurate.

When joining tables and running a COUNT on the select, you can only count the total number of rows returned. You can't COUNT based on the number of rows returned for a single table in the JOIN. If you absolutely must use COUNT, you have to run more than 1 query (1 for each COUNT you need to run) or use sub-queries that run the COUNT for the particular condition you're looking for.

This query is possible to run as a single query, but COUNT is not the solution. You use a combination of CASE and SUM. We run a CASE..WHEN clause that tests each row to see if the action that has been joined is a goal or an assist. If it is a goal, we give the goals column a value of 1, and if it's an assist we give the assists column a value of 1. Then we run an aggregate function (SUM) to add up all the 1s for goals and assists, and GROUP BY the player id. This gives you a single row for each player with the total # of goals and assists they earned even for the players that earned 0.

SELECT 
    p.payername, 
    SUM(CASE a.type WHEN 'goal' THEN 1 ELSE 0 END) goals, 
    SUM(CASE a.type WHEN 'assist' THEN 1 ELSE 0 END) assists
FROM Player p
LEFT JOIN Actions a ON a.player_id = p.id
GROUP BY p.id
LIMIT 0, 30

I hope that helps you out and makes sense to you. You can check out the documentation for CASE to get some more insight if you're still confused.

0

精彩评论

暂无评论...
验证码 换一张
取 消