【问题标题】:How to count only the record in left join?如何只计算左连接中的记录?
【发布时间】:2018-12-03 19:44:25
【问题描述】:

我需要计算在特定比赛中参加特定比赛的特定球队中特定球员的进球数。 我有三张桌子:

  1. 比赛:包含一支球队为特定比赛(回合)进行的所有比赛
  2. 玩家包含玩家的详细信息,例如:姓名、姓氏、身高等...
  3. Goal:包含该球员在一场比赛中的所有进球

这是我的查询:

$query = "SELECT
COUNT(*) AS goal_scored,
p.first_name AS first_name,
p.last_name AS last_name
FROM `match` m
LEFT JOIN goal g ON g.match_id = m.id
LEFT JOIN player p ON g.player_marker_id = p.id
WHERE m.round_id = :round_id
AND (m.home_team_id = :team_id OR m.away_team_id = :team_id)
GROUP BY p.id
ORDER BY goal_scored DESC
LIMIT 5";

在查询的第一部分,我尝试使用goalplayer 上的连接来选择搜索球队的球员打进的所有进球。 我过滤了与competition.id相对应的round的结果。

我期待在特定比赛中返回球队的最佳射手。

数据示例

匹配:

id | home_team_id | away_team_id | 
 1        95            121
 2       203            95
 3       95             122

目标:

id | player_marker_id | match_id | team_id | result  | type
 1         1005            1           95      1 - 0   1
 2         1005            1           95      1 - 0   2
 3         1005            2           95      2 - 1   1
 4         1006            3           95      1 - 0   1

玩家:

id    | first_name | surname 
1005    Benedetto    Ismael
1006    Ramon        Abila 

如您在表match 中看到的,我有3 条记录,这意味着95 球队已经打了3 场比赛。 这支球队有两名球员,球员Benedetto打进了2球,那支球队的最佳射手也是,预期结果应该是:

Benedetto
Ramon

但我得到goal_scored 的错误结果,例如3 进球,这是错误的,因为type 在此范围内并不重要。 type 只是告诉我是哪种类型的进球,特别是 1 是开局的进球,2 是普通进球。一个目标可以有多种类型,最多为 2 个。

另外,我发现了另一个错误,不同的球员可以在同一场比赛中得分,但是goal_scored的结果是不正确的,因为我只需要计算加入的特定球员的进球数,而不是球队的所有球员。

如何解决我的查询问题?

生产成果

SELECT * FROM `match` m 
LEFT JOIN goal g ON m.id = g.match_id AND g.player_marker_id = 68165 
WHERE m.round_id = 488 AND (m.home_team_id = 95 OR m.away_team_id = 95)

【问题讨论】:

  • 类型2是什么意思?我正在查看目标,我可以看到玩家 1005 有 3 个目标。您可能还需要按 match_id 分组。也做 COUNT(DISTINCT g.id)
  • @Monofuse type = 1 是开局的进球,type = 2 是简单的进球,我也有 type = 3 的点球,type = 4 错误的点球
  • 那么我唯一能看到的是你需要在 g.match_id 上进行分组。唯一一次 Benedetto 打进 2 球是如果您只考虑 id 为 1 的比赛。
  • @Monofuse 请检查我的更新
  • 我知道这已经解决了,但我会向你推荐枚举标志。不必两次插入具有类型差异的相同数据,您可以将其存储一次,其值等于两者。

标签: mysql sql pdo


【解决方案1】:

我不明白你的问题。为什么你有left joins?

根据我对您数据的解释,您只想查看带有type = 1 的目标。那么,这是否符合您的要求?

SELECT p.first_name AS first_name,
       p.last_name AS last_name,
       COUNT(*) AS goal_scored
FROM player p JOIN
     goal g
     ON g.player_marker_id = p.id JOIN
     `match` m
     ON g.match_id = m.id
WHERE m.round_id = :round_id AND
      :team_id IN (m.home_team_id, m.away_team_id) AND
      g.type IN (1, 2)
GROUP BY p.first_name, p.last_name
ORDER BY goal_scored DESC
LIMIT 5;

只有当你想要没有进球的球员时,你才会使用LEFT JOIN

【讨论】:

  • 请查看我的更新,图片中显示的结果是球员打进的正确进球:9球。问题是类型,事实上我也有重复的行,这就是总数不正确的原因,我不明白我该如何管理。您的查询返回 4,但 Benedetto 的正确结果是 9
  • 因为@jidic 将类型限制为 1。将其更改为 g.type in (1,2) 即可获得所需的内容
  • @Livius 我把它改成了:g.type = 1 OR g.type = 2 我得到了完全错误的结果,现在我有一个球员进了 74 个球,这是不可能的
  • 你在这个 OR 周围有父母亲吗?为什么不“在 (1,2) 中”?
  • @Livius 没有看到 gordon 答案的编辑,这项工作非常感谢,我被困在这几个小时
猜你喜欢
  • 1970-01-01
  • 2013-12-05
  • 1970-01-01
  • 1970-01-01
  • 2010-10-18
  • 2016-07-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多