SQL多个内连接导致SUM结果错误

4
我的数据库示例(在底部有SQLFiddle链接):
我有几个表:
表Login
1. User_ID(整数) 2. Email(varchar) 3. Passwort 4. Session ID
表Business
5. ID_Login_ID_Business(整数) 6. NameOfCompany(varchar) 7. NameContact(varchar) 8. ID_Location_FK(整数) 9. ID_BalancesheetInput_FK(整数) 10. ID_Balancesheetoutput(整数)
表ID_BalancesheetInput
11. ID 12. FK_Business_ID(整数) 13. RessourceName(varchar50) 14. Amount(十进制) 15. Unit_Fk(整数) 16. TypeOfRessource_FK(整数)
表Units
17. Unit_id 18. Unit
表TypeOfRessource 19. ID_Type 20. Type SQL应该检查Buisness中所有与BalancesheetInput中FK_Business_ID相等的ID_Login_ID_Business(外键)项,对具有相同RessourceName的所有金额进行求和,并简单添加typeofRessource以检查正确的Unit。
例如:
表Business
ID、NameOfCompany、ID_BalancesheetInput_FK
1 Apples 1 2 Minisoft 2
表BalancesheetInput
ID、FK_Business_ID、RessourceName、Amount、Unit_FK、TypeOFRessource_FK
1、1、电力、100、3、2 2、1、热能、200、3、2 3、1、热能、150、3、2 4、1、轻燃油、10、3、2 5、1、螺丝钉、200、3、2 6、1、水、200、4、3
表Units
单位ID、单位
  • 1,件
  • 2,吨
  • 3,千瓦时
  • 4,平方米
  • 5,升

表格 TypeOFRessource

ID_Type, 类型

  • 1,资产
  • 2,能源
  • 3,材料

以下语句试图捕获所选业务的资源,并计算具有相同名称(例如电力)的条目。它们属于同一公司,但出现了问题。

每次我使用我的SQL语句:

"SELECT DISTINCT "
           . "BalancesheetInput.RessourceName AS Rn, "
           . "Units.Unit AS En, "
           . "SUM(BalancesheetInput.Amount) AS TotalAmount "
           . "FROM Business"
           . "INNER JOIN BalancesheetInput ON FK_Business_ID = 1 "
           . "INNER JOIN Units ON Unit_FK = Unit_ID "
           . "INNER JOIN TypeOfRessource ON TypeOf Ressources = 2 "
           . "GROUP BY BalancesheetInput.RessourceName ");

结果:

轻质燃料油 60 千瓦时 能源 - 电力 600 千瓦时 能源 - 热能 2100 千瓦时

看起来他每行都添加了6倍的量。

我想要的结果:

轻质燃料油 10 千瓦时 能源 - 电力 100 千瓦时 能源 - 热能 350 千瓦时

这里是带有所有内容工作版本的SQLFiddle

如果您需要更多信息,只需告诉我需要什么帮助解决问题。


1
该GROUP BY查询无效。您使用的是哪个dbms?(通用的GROUP BY规则是:“如果指定了GROUP BY子句,则SELECT列表中的每个列引用必须标识一个分组列或是集合函数的参数。”) - jarlh
我正在使用MySQL ServerType的phpMyAdmin,表格是InnoDB。 - Sires
大多数数据库在 group by 没有所有必需的字段时会报错。MySql 在这方面似乎有所不同,这可能会导致混淆。 - LukStorms
@LukStorms,旧版MySQL存在这种奇怪的行为。新版MySQL则不会,也就是说,如果尝试执行该查询,将会引发错误。 - jarlh
我明白了。那么我猜Sires使用的是旧版本,因为他的版本接受了那个SQL语句。SQL Fiddle似乎也没有问题。 - LukStorms
2个回答

2

Luk Storms和我得出了相同的答案,这是我制作的SQLFiddle链接。

提示:如果在JOIN语句中使用SELECT *,您将看到为每个BalancesheetInput创建一个具有六行的表格; 每种公司名称和能源类型的组合都会创建一行。我们使用WHERE子句来缩小重复的行。通常,这比SELECT DISTINCT更好。

此外,“Screws”被错误地归类为“Energie”,而不是“Materiel”。


1

使用表的别名有助于编程。此外,应该在字段上创建适当的连接,而不是连接应该在where子句中的值。
最好确保GROUP BY具有您在选择中使用的所有字段(忽略函数中使用的字段)。
特别是在使用MySql时。

SELECT  
bs.RessourceName AS Rn, 
u.Unit AS En, 
SUM(bs.Amount) AS TotalAmount 
FROM Business b
INNER JOIN BalancesheetInput bs ON bs.FK_Business_ID = b.ID
INNER JOIN Units u ON u.Unit_ID = bs.Unit_FK
INNER JOIN TypeOfRessource t ON t.ID_Type = bs.TypeOFRessource_FK
WHERE b.NameOfCompany = 'Apples' 
AND bs.RessourceName = 'electricity'
GROUP BY bs.RessourceName, u.Unit

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接