SQL使用count后加入行

时间:2013-10-07 04:16:09

标签: mysql sql join count union

我正在尝试显示团队#1中的玩家列表和他们的统计数据,这里是表格

表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列中的COUNT 辅助 - COID(a1_id)+ COUNT(a2_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)

这会返回玩家的正确目标数

然而,当我把它们全部放在一起时,统计数据是错误的,当我知道应该有三个时它只显示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

3 个答案:

答案 0 :(得分: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

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

答案 1 :(得分:0)

您需要添加GROUP BY(另请参阅SQL GROUP BY Statement

  

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)

答案 2 :(得分: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)