2

我正在尝试显示来自第 1 队的球员列表以及与他们一起使用的统计数据,这里是表格

表一:球员

╔═══════════════════════════╗
║ id | fname | lname | team ║
╠═══════════════════════════╣
║ 1 | Jason | McFee | 1     ║
║ 2 | John | Smith  | 1     ║
║ 3 | Jack | Doe    | 1     ║
║ 4 | Wayne | Gretzky | 2   ║
╚═══════════════════════════╝

表 2:events_goals

╔═════════════════════════╗
║ id  g_id  a1_id  a2_id  ║
╠═════════════════════════╣
║ 1   1  2  3             ║
║ 2   3  1  2             ║
║ 3   2  1  NULL          ║
╚═════════════════════════╝

我想要得到的是这个
名字 - 从表
目标中连接 - 计数所有时间玩家 ID 在 g_id 列辅助
- 计数(a1_id)+ 计数(a2_id)所有时间玩家 ID 在这些列中的任何一个中点
- 总和进球+助攻

╔══════════════════════════════════════╗
║ id | name | goals | assists | points ║
╠══════════════════════════════════════╣
║ 1   J.McFee    1      2          3   ║
║ 2   J.Smith    1      2          3   ║
║ 3   J.Doe      1      1          2   ║
╚══════════════════════════════════════╝

我试图做的

>SELECT id,
>CONCAT_WS(', 'SUBSTR(fname, 1, 1), lname) name,
>FROM players 
>WHERE teamid = 1

这让我返回了团队中 ID 为 1 的所有球员的姓名,其中的姓名格式正确,没问题。

我可以通过使用来计算单个玩家的数量

>SELECT COUNT(g_id) FROM events_goals WHERE id = (playerid)

这将为玩家返回正确的进球数

然而,当我把它们放在一起时,统计数据是错误的,当我知道应该有 3 行时它只显示 1 行

> SELECT a.id,
> CONCAT_WS(', 'SUBSTR(a.fname, 1, 1), a.lname) name,
> (COUNT(b.g_id))goals, 
> (COUNT(c.a1_id))a1, 
> (COUNT(d.a2_id))a2 
> FROM players a
> LEFT JOIN events_goals b ON a.id = b.g_id 
> LEFT JOIN events_goals c ON a.id = c.a1_id 
> LEFT JOIN events_goals d ON a.id = d.a2_id WHERE teamid = 1
4

3 回答 3

1

这是您要查找的查询:

SELECT
  p.id,
  CONCAT_WS(', ', SUBSTR(p.fname, 1, 1), p.lname) name,
  COALESCE(eg_goals.goals, 0) goals, 
  COALESCE(eg_assists1.assists, 0) + COALESCE(eg_assists2.assists, 0) assists,
  COALESCE(eg_goals.goals, 0) + COALESCE(eg_assists1.assists, 0) + COALESCE(eg_assists2.assists, 0) points
FROM players p
LEFT JOIN (
  SELECT g_id, COUNT(g_id) goals FROM events_goals
  GROUP BY g_id
) eg_goals ON p.id = eg_goals.g_id
LEFT JOIN (
  SELECT a1_id, COUNT(a1_id) assists FROM events_goals
  GROUP BY a1_id
) eg_assists1 ON p.id = eg_assists1.a1_id
LEFT JOIN (
  SELECT a2_id, COUNT(a2_id) assists FROM events_goals
  GROUP BY a2_id
) eg_assists2 ON p.id = eg_assists2.a2_id
WHERE p.team = 1

您应该认真重新考虑重新设计您的架构。将这些“事件”混合在同一张表中会导致可怕且难以维护的查询。

于 2013-10-07T05:07:56.983 回答
0

您需要添加一个GROUP BY(另请参见SQL GROUP BY 语句

GROUP BY 语句与聚合函数一起使用,以按一列或多列对结果集进行分组。

**SQL GROUP BY Syntax**

SELECT column_name, aggregate_function(column_name)
FROM table_name
WHERE column_name operator value
GROUP BY column_name;



SELECT a.id,
CONCAT_WS(', 'SUBSTR(a.fname, 1, 1), a.lname) name,
(COUNT(b.g_id))goals, 
(COUNT(c.a1_id))a1, 
(COUNT(d.a2_id))a2 
FROM players a
LEFT JOIN events_goals b ON a.id = b.g_id 
LEFT JOIN events_goals c ON a.id = c.a1_id 
LEFT JOIN events_goals d ON a.id = d.a2_id 
WHERE teamid = 1
GROUP BY a.id,
CONCAT_WS(', 'SUBSTR(a.fname, 1, 1), a.lname)
于 2013-10-07T04:18:24.210 回答
0

使用COALESCE

SELECT a.id,
        CONCAT_WS(', ', SUBSTR(a.fname, 1, 1), a.lname) name,
        (COUNT(b.g_id)) goals,  
        ((COALESCE(COUNT(c.a1_id),0)) + (COALESCE(COUNT(c.a2_id),0))) assists, 
        (COUNT(COALESCE(c.a1_id,0)) + COUNT(COALESCE(c.a2_id,0)) + COUNT(COALESCE(b.g_id,0))) points 
        FROM players a
        LEFT JOIN events_goals b ON a.id = b.g_id 
        LEFT JOIN events_goals c ON a.id = c.a1_id 
        LEFT JOIN events_goals d ON a.id = d.a2_id 
        WHERE a.teamid = 1
        GROUP BY a.id,
        CONCAT_WS(', ', SUBSTR(a.fname, 1, 1), a.lname)
于 2013-10-07T04:32:35.667 回答