这是我正在开发的系统数据库的一部分:
我需要创建一个 SQL 语句来返回客户的名称以及该客户的所有销售额的总和。换句话说,客户在销售中花费的金额。
让我们创建一个示例:
Table client:
cliId = 1, cliName = "client1";
Table product:
proId = 1, proName = "prod1", proBaseValue = 3;
proId = 2, proName = "prod2", proBaseValue = 2.5;
proId = 3, proName = "prod3", proBaseValue = 1;
Table sale:
salId = 1, salAddition = 0, salDiscount = 1, sal_cliId = 1;
salId = 2, salAddition = 2, salDiscount = 0, sal_cliId = 1;
salId = 3, salAddition = 0, salDiscount = 2, sal_cliId = 1;
Table saleitems (Weak Entity from the relationship between sale and product):
sli_salId = 1, sli_proId = 2, sliRealValue = 2.5, sliQuantity = 1;
sli_salId = 2, sli_proId = 2, sliRealValue = 2.5, sliQuantity = 2;
sli_salId = 2, sli_proId = 3, sliRealValue = 1, sliQuantity = 1;
sli_salId = 3, sli_proId = 1, sliRealValue = 3, sliQuantity = 1;
sli_salId = 3, sli_proId = 2, sliRealValue = 2.5, sliQuantity = 1;
sli_salId = 3, sli_proId = 3, sliRealValue = 1, sliQuantity = 2;
在第一种情况下,忽略“salAddition”和“salDiscount”,我使用了以下 SQL 语句:
select cliName, (sum(sliRealValue * sliQuantity))
from exampledb.client join exampledb.sale join exampledb.saleitems
where cliId = sal_cliId and
salId = sli_salId
group by cliId;
而且效果很好。但是问题是当我尝试将“salAddition”和“salDiscount”包含在数学中时。理论上,SQL 语句为:
select cliName, (sum(sliRealValue * sliQuantity) + sum(salAddition) - sum(salDiscount))
from exampledb.client join exampledb.sale join exampledb.saleitems
where cliId = sal_cliId and
salId = sli_salId
group by cliId;
请注意,我需要对所有销售的所有添加和所有折扣求和才能使其正常工作。这并不简单......
根据上面给出的示例,忽略附加值(value)和折扣,预期总值(value)为 16 美元,包括这些属性在内,总值(value)应为 15 美元,但我找到的结果是 13 美元。 在测试代码和值(value)组合几个小时后,我注意到,在第一次销售中,附加值和折扣值被乘以 1,在第二次销售中,相同的值被乘以2,在第三次销售中,值乘以 3 等等...(不,它与 Id 值无关)。
我尝试将 ...+ sum(salAddition) - sum(salDiscount)...
替换为 ...+ sum(salAddition - salDiscount)...
但我发现了相同的值(和问题)。
拜托,谁能告诉我BUG是怎么回事,如果可能的话,告诉我解决这个问题的方法?我刚刚在 MySQL Workbench 中发现了错误吗?
提前致谢。
最佳答案
虽然你没有具体写,但只有在每次销售而不是每次销售的产品应用额外金额和折扣时,数学才会计算出来。但是,由于您总结了每个产品的额外金额和折扣。只需检查不使用分组依据和总和的查询即可完全理解。
这意味着,您必须首先计算每次销售的实际值(value),然后加上和减去额外的东西和折扣。
select c.cliName, sum(t.salevalue+s.salAddition-s.discount) as totalsalevalue
from (select sli_salId, sum(sliRealValue * sliQuantity) as salevalue
from saleitems
group by sli_salId) t
inner join sale s on t.sli_salId=s.salId
inner join client c on c.cliId=s.sal_cliId
group by c.cliId
两条评论:
请使用显式的
join
语法,其中连接条件在on
子句中,而不是在where
中。在性能方面没有区别,但会使您的代码更易于阅读。在 SQL99 标准下,您可以在选择列表中包含不在分组依据列表中的字段,也不会对其进行聚合,前提是它们在功能上依赖于分组依据列表中的字段。 Mysql从mysql v5.7.5开始遵循这个标准,所以你会没事的。
关于在同一 Sql 语句中使用多个 sum() 聚合函数时出现 Mysql Workbench 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45899593/