来自多个JOINS的SQL不正确的SUMS

时间:2015-04-18 19:59:30

标签: mysql database

我试图在MySQL中使用Joins和Sums对多个表进行求和并且没有取得多大成功。

我的表格(删除了不必要的列)

学生

idStudent   studentname   studentyear
1           foobar        11
2           barfoo        11
3           thing         8

Athletics_Results

idResult   idStudent   points
1          1           14
2          1           11
3          3           7
4          2           9

Team_Results

idTeamResults   year   points
1               11     9
2               8      8
3               7      14

所以让我解释一下这些表格,因为我承认他们的名字和设计都很糟糕。

学生掌握每位学生的基本信息,包括他们的年份和姓名。每个学生都有一个唯一的ID。

Athletics_Results存储田径比赛的结果。 idStudent列是外键,与student列中的idStudent相关。所以学生foobar(idStudent 1)在这个例子中得了14分和11分。

Team_Results存储多个学生参与的事件的结果。它只存储年份组和点数。

目标

我希望能够每年产生一个积分总和 - 结合来自athletics_results和team_results。 EG:

year   points
7      14     <-- No results in a_r, just 14 points in t_r
8      15     <-- 7 points in a_r (idResult 4) and 8 in t_r
11     43     <-- 14, 11, 9 points in a_r and 9 in t_r

我尝试了什么 出于测试目的,我还没有尝试过将a_r得分和t_r得分结合起来,而是将它们分成两列,这样我才能看到发生了什么。

我尝试的第一个查询:

SELECT students.studentyear as syear, SUM(athletics_results.points) as score, SUM(team_results.points) as team_score
FROM students
JOIN team_results ON students.studentyear = team_results.year
JOIN athletics_results ON students.idStudent = athletics_results.idStudent
GROUP BY syear;

这给了每年不同的行(根据需要),但是SUMS不正确。我了解到这是因为没有对连接进行分组。

然后我创建了这段代码:

SELECT studentyear as sYear, teamPoints, AthleticsPoints
FROM students st

JOIN    (SELECT year, SUM(tm.points) as teamPoints
        FROM team_results tm
        GROUP BY year) tr ON st.studentyear = tr.year 

JOIN    (SELECT idStudent, SUM(atr.points) as AthleticsPoints
        FROM athletics_results atr
        ) ar ON st.idStudent = ar.idStudent

哪个给出了正确的SUMS,但只返回了一年的小组行(例如11年级的分数)。

编辑 - SQLFiddle:http://sqlfiddle.com/#!9/dbc16/。这是我的实际测试数据,它比我在这里发布的数据更大。

3 个答案:

答案 0 :(得分:1)

http://sqlfiddle.com/#!9/ad111/7

SELECT tr.`year`,  COALESCE(tr.points,0)+COALESCE(SUM(ar.points),0)
FROM Team_Results tr
LEFT JOIN Students s
ON tr.`year`=s.studentyear
LEFT JOIN Athletics_Results ar
ON s.idStudent = ar.idStudent
GROUP BY tr.year

根据您提供的评论和小提琴 检查http://sqlfiddle.com/#!9/dbc16/3

SELECT tr.`year`,  COALESCE(tr.points,0)+COALESCE(SUM(ar.points),0)
FROM (
  SELECT `year`, SUM(points) as points
  FROM Team_Results
  GROUP BY `year`) tr
LEFT JOIN Students s
ON tr.`year`=s.studentyear
LEFT JOIN Athletics_Results ar
ON s.idStudent = ar.idStudent
GROUP BY tr.year

答案 1 :(得分:0)

可以通过多种方式完成。我的第一个想法是:

SELECT idStudent, year, SUM(points) AS totalPoints FROM (
SELECT a.idStudent, c.year, a.points+b.points AS points
FROM students a
INNER JOIN Athletics_Results b ON a.idStudent=b.idStudent
INNER JOIN Team_Results c ON a.studentyear=c.year) d
GROUP BY idStudent,year

答案 2 :(得分:0)

试试这个http://sqlfiddle.com/#!9/2bfb1/1/0

SELECT 
    year, SUM(points)
FROM
    ((SELECT 
        a.year, SUM(b.points) AS points
    FROM
        student a
    JOIN at_result b ON b.student_id = a.id
    GROUP BY a.year) UNION (SELECT 
        a.year, SUM(a.points) AS points
    FROM
        t_result a
    GROUP BY a.year)) c
GROUP BY year;

关于你的数据我得到了:

   year      points 
    7          14
    8          15
    11         43