2017-08-26 105 views
1

这是一个系统的数据库的一部分,我开发:MySQL工作台错误

my database

我需要创建一个返回的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; 

在1日的情况下,无视 “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; 

请注意,我需要总结所有的添加,并从所有销售的所有折扣优惠,以使其发挥作用。这并不简单......

根据上面给出的例子,忽略附加值和折扣,预期的总价值将是16美元,并且包括这些属性,总价值应该是15美元,但结果I发现是13美元。 经过几个小时测试的代码和价值组合,我注意到,在第一次销售,增加和折扣价值乘以乘以1,在第二次销售,相同的价值乘以2,在第三次销售,价值乘以3等等...(并且不,它与Id值无关)。

我试图用...+ sum(salAddition - salDiscount)...取代...+ sum(salAddition) - sum(salDiscount)...但是我找到了相同的值(和问题)。

请问谁能告诉我这个BUG是怎么回事,如果可能的话,告诉我一种解决这个问题的方法?我在MySQL Workbench中发现了一个错误吗?
在此先感谢。

+0

sql语句由mysql执行,而不是mysql workbench,所以这不能成为工作台中的bug – Shadow

回答

0

尽管您没有专门编写,但数学只适用于如果每笔销售应用附加金额和折扣,而不是每件产品的每次销售。但是,由于您总结了每件产品的额外金额和折扣。只要检查你的查询没有集团和完全理解的款项。

这意味着,您必须首先总结每次销售的实际价值,然后添加和减去额外的东西和折扣。

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 

两点意见:

  1. 请使用显式join语法,其中连接条件是on子句中,而不是在where。性能方面没有区别,但会使代码更易于阅读。

  2. 在SQL99标准下,您可以在选择列表中包含不在分组依据列表中的字段,也不能聚合,只要它们在功能上依赖于分组依据列表中的字段。自从mysql v5.7.5以来,Mysql遵循这个标准,所以你会好起来的。

+0

谢谢。有效!!但是,仍然可以为我们解释你的第二条评论吗?另外,我很抱歉不把连接条件放在'on'子句中。事实上,它使代码更美观。再次感谢! –

+0

查询首先汇总每笔销售的销售物品,以便您每销售一行。这发生在子查询中。然后它以折扣和附加金额加入销售表。这可以防止重复额外的金额和折扣。正如我写的,运行你原来的查询,不用总结和分组,你会明白出了什么问题。 – Shadow