MySQL SUM()给出了意想不到的答案

时间:2013-09-18 19:09:03

标签: mysql

我有以下SQL:

SELECT
          t.amount
        FROM
          transactions t
        JOIN contracts c ON t.contractId = c.id
        JOIN insertions i ON c.id = i.contractId
        JOIN magazines m ON i.magazineId = m.id
        WHERE m.id = 26
          AND t.isChargedBack IS FALSE
          AND t.`timestamp` >= '2013-09-12'
          AND t.`timestamp` <= date_add('2013-09-12',interval 1 month)
        GROUP BY 
          t.id;

哪个收益率:

1100
800
1025
500
1200
552
395
395
1170
1000
675

我只想要这个结果的SUM。我期待8812。

所以我使用以下SQL:

SELECT
          IFNULL(SUM(t.amount),0)
        FROM
          transactions t
        JOIN contracts c ON t.contractId = c.id
        JOIN insertions i ON c.id = i.contractId
        JOIN magazines m ON i.magazineId = m.id
        WHERE m.id = 26
          AND t.isChargedBack IS FALSE
          AND t.`timestamp` >= '2013-09-12'
          AND t.`timestamp` <= date_add('2013-09-12',interval 1 month)
        GROUP BY 
          t.id;

这是我的结果:

39600
9600
61500
9000
43200
49680
14220
5925
7020
36000
72900

????

1 个答案:

答案 0 :(得分:1)

您的原始查询存在问题。它没有做你认为它正在做的事情。您按t.id汇总,但选择t.amount。这意味着MySQL正在选择一个任意值。

为什么会这样?一种可能性是,以下 适用于每笔交易:

    SELECT sum(t.amount)
    FROM transactions t
    JOIN contracts c ON t.contractId = c.id
    JOIN insertions i ON c.id = i.contractId
    JOIN magazines m ON i.magazineId = m.id
    WHERE m.id = 26
      AND t.isChargedBack IS FALSE
      AND t.`timestamp` >= '2013-09-12'
      AND t.`timestamp` <= date_add('2013-09-12',interval 1 month)
    GROUP BY t.id;

如果是这样,只需删除group by即可获得正确的总数。

另一种可能性是join s乘以行。我怀疑是insertions。如果是这种情况,那么t.amount正在重复,您想要的查询只会选择一个值:

    SELECT min(t.amount)
    FROM transactions t
    JOIN contracts c ON t.contractId = c.id
    JOIN insertions i ON c.id = i.contractId
    JOIN magazines m ON i.magazineId = m.id
    WHERE m.id = 26
      AND t.isChargedBack IS FALSE
      AND t.`timestamp` >= '2013-09-12'
      AND t.`timestamp` <= date_add('2013-09-12',interval 1 month)
    GROUP BY t.id;

如果这是问题,那么要获得全部总和,您可以使用子查询:

select sum(amount)
from (SELECT min(t.amount) as amount
      FROM transactions t
      JOIN contracts c ON t.contractId = c.id
      JOIN insertions i ON c.id = i.contractId
      JOIN magazines m ON i.magazineId = m.id
      WHERE m.id = 26
        AND t.isChargedBack IS FALSE
        AND t.`timestamp` >= '2013-09-12'
        AND t.`timestamp` <= date_add('2013-09-12',interval 1 month)
      GROUP BY t.id
     ) t