mysql sum()使用多个联接返回双值
我使用多种货币,如美元、人民币、卢比。 它工作正常,但今天我注意到sum()的双倍值,比如b.GrandTotal应该是11500,但它的返回值是23000mysql sum()使用多个联接返回双值,mysql,sql,Mysql,Sql,我使用多种货币,如美元、人民币、卢比。 它工作正常,但今天我注意到sum()的双倍值,比如b.GrandTotal应该是11500,但它的返回值是23000 select a.ClientID, f.Currency, a.OrganizationName, COALESCE(sum(b.GrandTotal),0) as SaleGrandTotal, COALESCE(sum(g.AmountReceived),0) as AmountReceived, COALESCE(sum(b.Gr
select
a.ClientID,
f.Currency,
a.OrganizationName,
COALESCE(sum(b.GrandTotal),0) as SaleGrandTotal,
COALESCE(sum(g.AmountReceived),0) as AmountReceived,
COALESCE(sum(b.GrandTotal - g.AmountReceived),0) as SaleBalanceRemaining,
COALESCE(sum(d.GrandTotal), 0) as PurchaseGrandTotal,
COALESCE(sum(e.AmountPaid), 0) as AmountPaid,
COALESCE(sum(d.GrandTotal - e.AmountPaid),0) as PurchaseBalanceRemaining,
COALESCE(sum(b.GrandTotal - g.AmountReceived),0) - COALESCE(sum(d.GrandTotal - e.AmountPaid),0) as Total
from na_clients as a
join na_currency as f
left join na_transaction as b
on a.ClientID = b.ClientID and b.CurrencyID = f.CurrencyID and b.IsActive = 1
left join na_recoverylogs as g
on b.TID = g.TID
left join na_purchase as d
on a.ClientID = d.ClientID and d.CurrencyID = f.CurrencyID and d.IsActive = 1
left join na_purchaselogs as e
on e.PID = d.PID
group by a.OrganizationName,f.Currency
order by a.OrganizationName
因此,结果应该是:
Table Client:
clientid,name,organizationName
1,client1,OrgName
2,client2,OrgName
Table Currency:
currencyid,cname
1,Dollar
2,Rupees
Table Transaction:
tid,clientid,currencyid,grandTotal,amountReceived,balanceremaining
1,1,1,11000,0,11000
2,1,1,500,0,500
Table recoveryLogs: // Another Error Here
id,tid,amountreceived
1,1,0
2,2,0
3,2,2000 // Again sum() multiply value - because of PID 2 is repeating
Table Purchase:
pid,clientid,currencyid,grandTotal,amountPaid,balanceRemaining
1,1,1,25000,0,25000
1,2,2,2,3000,1000,2000
Now I am using sum(b.grandTotal) instead of 11500 it return 23000
Table PurchaseLogs: // Another Error Here
id,pid,amountpaid
1,1,0
2,2,1000
3,1,1000 // Again sum() multiply value - because of PID 1 is repeating
但我得到的结果是:
Client: Client1
SaleGrandTotal: 11500
AmountReceived: 0
SaleBalanceRemaining: 11500
PurchaseGrandTotal: 25000
AmountPaid: 0
PurchaseBalanceRemaining: 25000
Total Amount: -13500
如果我从查询中删除purchase子句(d和e)或transaction(b和g)子句,它可以单独工作。数据加倍的原因是您的
ClientID在transaction和purchase表中出现的次数不同,因此不是1对1匹配ClientID=1
和CurrencyID=1
在交易中出现两次,在购买中只出现一次。当您加入表时,将产生一组1 x 2=2ClientID
记录,其中一些字段重复数据。因此,重复输入的总和将加倍。如图所示:
Client: Client1
SaleGrandTotal: 23000
AmountReceived: 0
SaleBalanceRemaining: 23000
PurchaseGrandTotal: 50000
AmountPaid: 0
PurchaseBalanceRemaining: 50000
Total Amount: -27000
考虑使用派生表分离两个表之间的聚合。然后,加入四个底层聚合(事务、购买、恢复日志、购买日志)进行最终查询。如果在ClientID
和CurrencyID
、TID
和PID
上进行聚合,则联接将以1对1进行匹配
Transaction Data | Purchase Data
row1: 1,1,1,11000,0,11000 | 1,1,1,25000,0,25000
row2: 2,1,1,500,0,500 | 1,1,1,25000,0,25000
您不使用客户机id分组的原因是什么?我只是每隔一个RDM在查看页面@WilliamBurnhamIn中使用ClientID作为参考,此聚合SQL查询将失败,因为您包含一个非聚合列,ClientID
,但不在GROUP BY
子句中指定它。MySQL运行在多个模式下,其中一个是仅完整分组方式(仅在MySQL 5.7.5中是默认设置)。只需不使用MySQL“扩展”来分组方式即可。始终在GROUPBY子句中包含所有非聚合列,这样可以避免错误。当您在“non determinate”(即您的猜测和我的一样)中从group by子句中排除列时,MySQL会做什么?实际上,它会为group by子句中未指定的非聚合列任意选择一些值。您真的在使用Microsoft的SQL Server吗?结果:-返回错误的结果,货币美元没有条目,它返回多行,如:巴基斯坦卢比,巴基斯坦卢比,美元,美元。上面的查询返回双结果,而不是2货币,其返回4-2用于transAgg,2用于purchAgg@Parfait请参阅将CurrencyID
添加到派生表的JOIN
中的更新。非常感谢@Parfait的回答和解释:)再次使用sum()返回双精度值。我刚刚在purchaseLogs和recoveryLogs中添加了条目。我已经更新了问题。请看一看@ParfaitYou将不得不分离日志(删除它们当前的左连接),并将它们单独聚合到另外两个派生表中,这一次连接到相应的transAgg和purchAgg派生表中。
SELECT
transAgg.ClientID, transAgg.Currency, transAgg.OrganizationName,
transAgg.SaleGrandTotal, recovLogAgg.SumOfAmtReceived,
(transAgg.SaleGrandTotal - recovLogAgg.SumOfAmtReceived) as SaleBalanceRemaining,
purchAgg.PurchaseGrandTotal, purchLogAgg.SumOfAmtPaid,
(purchAgg.PurchaseGrandTotal - purchLogAgg.SumOfAmtPaid) as PurchaseBalanceRemaining,
((transAgg.SaleGrandTotal - recovLogAgg.SumOfAmtReceived) -
(purchAgg.PurchaseGrandTotal - purchLogAgg.SumOfAmtPaid)) As [Total]
FROM
(SELECT
a.ClientID, f.CurrencyID, f.Currency, a.OrganizationName,
COALESCE(sum(b.GrandTotal),0) as SaleGrandTotal
FROM na_clients as a
INNER JOIN na_currency as f
LEFT JOIN na_transaction as b
ON a.ClientID = b.ClientID
AND b.CurrencyID = f.CurrencyID
AND b.IsActive = 1
GROUP BY a.ClientID, a.OrganizationName, f.CurrencyID, f.Currency
ORDER BY a.OrganizationName) As transAgg
INNER JOIN
(SELECT
a.ClientID, f.CurrencyID, f.Currency, a.OrganizationName,
COALESCE(sum(d.GrandTotal), 0) as PurchaseGrandTotal
FROM na_clients as a
INNER JOIN na_currency as f
LEFT JOIN na_purchase as d
ON a.ClientID = d.ClientID
AND d.CurrencyID = f.CurrencyID
AND d.IsActive = 1
GROUP BY a.ClientID, a.OrganizationName, f.CurrencyID, f.Currency
ORDER BY a.OrganizationName) As purchAgg
ON transAgg.ClientID = purchAgg.ClientID
AND transAgg.CurrencyID = purchAgg.CurrencyID
INNER JOIN
(SELECT
g.TID, COALESCE(sum(g.AmountReceived),0) As SumOfAmtReceived
FROM na_recoverylogs as g
GROUP BY g.TID) As recovlogAgg
ON transAgg.TID = recovlogAgg.TID
INNER JOIN
(SELECT
e.PID, COALESCE(sum(e.AmountPaid),0) As SumOfAmtPaid
FROM na_purchaselogs as e
GROUP BY e.PID) As purchlogAgg
ON purchAgg.PID = purchlogAgg.PID