在MySQL使用sum的错误结果

时间:2013-04-19 21:10:33

标签: mysql sum

我有一个包含大量数据的视图。我可以使用子查询获得此结果(数据可以正常并优化):

+------------+
| attendance |
+------------+
|        319 |
|        102 |
|        598 |
|        113 |
|          6 |
|        279 |
|        366 |
|        146 |
|        669 |
|        205 |
|        123 |
+------------+

下次有些用户更新数据时,会显示:

+------------+
| attendance |
+------------+
|        319 |
|        102 |
|        598 |
|        113 |
|          7 |
|        279 |
|        253 |
|        146 |
|        669 |
|        561 |
|        123 |
+------------+

哪个好,'因为更新信息的用户是之前有6个作为出勤的用户。

但问题来自于我将这些数据用作临时表,然后我做了:

 SELECT SUM(attendance) AS total FROM ( /* Subquery returning the above table */)

导致它返回(首先是一个用户有6个作为出勤率):

+-------+
| total |
+-------+
|  3169 |
+-------+

用7:

+-------+
| total |
+-------+
|  3128 |
+-------+

什么时候应该是3170 !!!

想法?

编辑1:粘贴完整查询。

SELECT SUM(att_member) AS total
FROM
    (SELECT attendance AS att_member
     FROM
         (SELECT id_branch_channel, id_member, attendance, TIMESTAMP, id_event
          FROM view_event_attendance
          WHERE id_event = 782
          ORDER BY TIMESTAMP DESC) AS temptable
     GROUP BY 
              id_member) AS total_attendance_temp

编辑2 :粘贴我从这里获得的查询帮助

Select only last value using group by at mysql

以下是视图的架构。

2 个答案:

答案 0 :(得分:1)

让我们解析查询,不管吗?

我假设view_event_attendance为参加活动的每位与会者(成员)都有一条记录。 id_event是该事件的FK,id_member对于与会者是FK。您的内部选择为您提供了参加活动#782

的所有成员的有序列表
SELECT id_branch_channel, id_member, attendance, TIMESTAMP, id_event
FROM view_event_attendance
WHERE id_event = 782
ORDER BY TIMESTAMP DESC

到目前为止,如此笨拙。现在,您将此查询包装在另一个中:

SELECT attendance AS att_member
FROM (subquery)
GROUP BY id_member

在大多数SQL dialetcs中,这只是一个语法错误。 MySQL允许这样做,但结果可能不是你想要的。您将获得参加该活动的每位id_member的出勤栏。您实际可能期望的是出勤率,但我在您的问题中没有这样说。在任何情况下,每个选定的字段都应该在您的GROUP BY子句中或使用聚合函数,例如

SELECT SUM(attendance) AS att_member
FROM (subquery)
GROUP BY id_member

SELECT attendance AS att_member
FROM (subquery)
GROUP BY id_member, attendance

说完了,我认为不需要使用子查询开头。假设您希望获得上述SUM,您可以将其重新编写为单个SQL查询:

SELECT SUM(attendance) AS att_member
FROM view_event_attendance
WHERE id_event = 782
GROUP BY id_member

如果你想要总数,你可以简单地省略GROUP BY条款,留下你的话:

SELECT SUM(attendance) AS att_member
FROM view_event_attendance
WHERE id_event = 782

如果这不能按预期工作,请更详细地描述您在view_event_attendance中实际存储的内容,以及您希望第二个查询计算的内容。

答案 1 :(得分:0)

正如@EdGibbs注意到的那样,子查询返回了糟糕的结果(我没有注意到)。所以我再次阅读我的代码和the answer to the other question I make reference,现在这些东西可以正常工作,通过这样做:

SELECT SUM(att_member) AS total
FROM
    (SELECT attendance AS att_member
     FROM
         (SELECT 
            id_branch_channel, 
            id_member, 
            substring(max(concat(from_unixtime(timestamp),attendance)) from 20) as attendance, 
            timestamp, 
            id_event
          FROM view_event_attendance
          WHERE id_event = 782
          GROUP BY id_event, id_member
          ORDER BY timestamp DESC) AS temptable
     ) AS total_attendance_temp

我做的唯一改变是:

  • 使用:substring(max(concat(from_unixtime(timestamp),attendance))来自20)作为出勤而非仅有出席。
  • 在第一个子查询中移动组。

所以问题不在MySQL的SUM函数中,而是在我的查询中。

感谢大家花时间帮我解决这个问题。您的建议可以帮助我找到答案。