具有JOIN时的SUM MySQL列

问题描述

我遇到了一个新手问题,试图对MysqL的结果集求和。

有2张桌子:

formalities
  - id
  - total
  - group_id
  - book_id
  - status_id

payments
  - id
  - amount
  - formality_id (FK)

考虑形式上的1:N关系,其中1个formality可以有1个或更多payments。 我需要以两种方式获取总和:

一个,通过从formalities.total获取总数,按预期工作:

SELECT SUM(formalities.total)
FROM formalities
WHERE group_id = 2 AND book_id = 23 AND status_id IN (1,3)

第二个,通过从payments.amount获取总数:

SELECT
    SUM(f.amount) AS total
FROM
(
    SELECT
        payments.amount
    FROM payments
    JOIN formalities ON payments.formality_id = formalities.id AND formalities.group_id = 2 AND formalities.book_id = 23 AND formalities.status_id IN (1,3)
    GROUP BY payments.id
) f

仅供参考:

  • 所有付款都与手续有关。
  • 所有手续至少要付款1次。
  • formalities.total始终等于其payments.amount的总和

我想知道第二个查询出了什么问题,因为总数不匹配。

顺便说一句,我正在处理最近迁移的数据库,因此这可能与错误的迁移有关,但是我需要确保查询正在执行我要寻找的事情。

解决方法

好吧,派生表f中的查询无效。 payments.amount要么必须在GROUP BY子句中,要么传递给聚合函数。较旧的MySQL或配置不正确的MySQL版本确实会破坏该规则,而不会发出进一步的警告。但这可能会产生有趣的结果,甚至可能无法再现。

SELECT sum(p.amount)
       FROM formalities f
            LEFT JOIN payments p
                      ON p.formality_id = f.id
       WHERE f.group_id = 2
             AND f.book_id = 23
             AND f.status_id IN (1,3);

据我所知,应该给您想要的结果。

另一件事:formalities.total似乎要为该形式保留所有payments.amount的总和。如果是这样,请删除列formalities.total。它是多余的,可能会导致不一致-可能是您现在正在遇到的问题。总额不应实现。为了方便起见,您可以创建一个包含总数的视图。类似于:

CREATE VIEW formalities_with_total
AS
SELECT f.id,sum(p.amount) total,f.group_id,f.book_id,f.status_id
       FROM formalities f
            LEFT JOIN payments p
                      ON p.formality_id = f.id
       GROUP BY f.id,f.status_id;