问题描述
有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;