我的数据库中有 2 条记录金额,我必须使用求和函数来显示总金额,但它显示并求和了两次
我在同一个查询中尝试了另一个求和函数并且它起作用了,但是当我第二次使用它时,它求和了两次。
$sql = "SELECT
mm.idno as idno,
TRIM(UPPER(CONCAT(mm.fname, ' ', mm.mname, ' ', mm.lname))) as fullname,
TRIM(UPPER(mm.branchname)) as branchname,
TRIM(UPPER(mm.address)) as outlet_address,
SUM(dr.totalamt) as total_amount,
SUM(drr.totalamt) as return_amount
FROM 8_membermain mm
LEFT JOIN 8_directsalessummary dr ON mm.idno = dr.idno
LEFT JOIN 8_drreturnsummary drr ON dr.idno = drr.idno
WHERE mm.status > 0 AND dr.status = 1
AND dr.ispaid = 'Full Payment'
AND dr.trandate BETWEEN '".$date1."' AND '".$date2."'
AND drr.trandate BETWEEN '".$date1."' AND '".$date2."'";
SUM(dr.totalamt) as total_amount
工作正常。唯一的问题是 SUM(drr.totalamt) as return_amount
最佳答案
根据您对问题的描述,听起来您的查询匹配两个 dr 行和一个 drr 行。如果有不止一个 drr 行,则 dr total 也将是错误的。这是因为联接返回联接表的所有可能组合。例如,如果有两个 dr 行,我们将调用 A 和 B,以及三个 drr 行 C、D 和 E,则结果(在组合成一行之前,由于使用了没有分组依据的 sum ) 将是:
A and C
A and D
A and E
B and C
B and D
B and E
对 dr 列求和时,A 和 B 的值各出现三次,结果是三倍的总和。并且在对 drr 列求和时,C、D 和 E 的值各遇到两次,导致总和加倍。
正确的解决方法是加入 dr 和 drr 的子查询,如 Tim 的回答所示。但有时,涉及的表很少,并且大多数表的每个分组中的记录很少,并且表具有主键或其他一些唯一列,您可以简单地将每个总和除以每个其他表中的行数(或1 如果没有行):
SELECT
...
SUM(dr.totalamt)/GREATEST(1,COUNT(DISTINCT drr.primarykey)) as total_amount,
SUM(drr.totalamt)/GREATEST(1,COUNT(DISTINCT dr.primarykey)) as return_amount
关于您的查询的其他一些评论:
您似乎打算在末尾添加一个 GROUP BY mm.idno
;否则,您的查询将返回与您的 where 条件匹配的任意 mm 记录的 mm 相关字段的数据,如果您的查询实际上找到多个 mm 记录,则上述技巧将无法正常工作。
您使用左连接,但随后在 where 子句中指定条件,如果没有找到行则为 false;这实际上使您的左连接成为内部连接。如果你想在没有 dr 或 drr 行的情况下查找 mm 行,你需要将条件移动到连接中,例如:
LEFT JOIN 8_directsalessummary dr ON mm.idno = dr.idno
AND dr.status = 1
AND dr.ispaid = 'Full Payment'
AND dr.trandate BETWEEN ...
此外,您正在使用 dr.idno 加入 drr;如果你想在没有 dr 记录的情况下查找 drr 记录,你应该使用 mm.idno 代替:
LEFT JOIN 8_drreturnsummary drr ON mm.idno = drr.idno
AND drr.trandate BETWEEN ...
关于mysql - SUM 函数添加记录两次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56848524/