您的查询最终会得到很多重复的结果。考虑以下更简单的情况:
Table: Project
ProjectID EQuantity
1 1
2 1
Table: Equipment
EquipID EPrice
1 1
2 1
Table: Fish
FishID
1
2
Table: Project_Equipment
ProjectID EquipID
1 1
1 2
2 1
2 2
Table: Project_Fish
ProjectID FishID
1 1
1 2
2 1
2 2
现在,让我们只看一个Project_Equipment
查询的结果:
SELECT p.projectid, e.eprice, pe.equantity FROM project p
INNER JOIN project_equipment pe ON pe.projectid=p.projectid
INNER JOIN equipment e ON e.equipid=pe.equipid
ProjectID EPrice EQuantity
1 1 1 // a
1 1 1 // b
2 1 1 // c
2 1 1 // d
正如预期的那样;每个项目使用的每件设备的价格和数量清单。但是你认为当我们这样做时会INNER JOIN
发生什么project_fish
?第一个结果中有两次项目 1 和两次项目 2,所以我们最终得到了该结果和project_fish
!
SELECT p.projectid, e.eprice, pe.equantity, f.fishid FROM project p
INNER JOIN project_equipment pe ON pe.projectid=p.projectid
INNER JOIN equipment e ON e.equipid=pe.equipid
INNER JOIN project_fish pf ON pf.projectid=p.projectid
ProjectID EPrice EQuantity FishID
1 1 1 1 // from a above
1 1 1 2 // from a above
1 1 1 1 // from b above
1 1 1 2 // from b above
2 1 1 1 // from c above
2 1 1 2 // from c above
2 1 1 1 // from d above
2 1 1 2 // from d above
这种复制将在每个内部连接中继续。您的价格将减少的金额并不总是 2 倍,它实际上取决于您所有联接的组合数量。
所以,你不能真正用这个特定的查询来做你想做的事情。相反,您必须分别计算每个关系的成本。然后你把所有这些加在一起。您可以通过分别选择每一个并将成本计算到一个ProjectID
和ProjectCost
列中,使用UNION
将它们完全连接起来,然后再次对结果进行分组ProjectID
并对各个ProjectCost
小计求和来做到这一点。
我解释得很糟糕,但可以将其视为对设备、鱼和工资成本的小计,然后将所有这些小计汇总到一张表中并将其相加。例如:
SELECT x.projectid, SUM(x.ProjectCost) FROM
(
SELECT p.projectid, SUM(e.eprice * pe.equantity) ProjectCost FROM project p
INNER JOIN project_equipment pe ON pe.projectid=p.projectid
INNER JOIN equipment e ON e.equipid=pe.equipid
GROUP BY p.projectid
UNION
SELECT p.projectid, SUM(f.fprice * pf.fquantity) ProjectCost FROM project p
INNER JOIN project_fish pf ON pf.projectid=p.projectid
INNER JOIN fish f ON f.fishid=pf.fishid
GROUP BY p.projectid
UNION
SELECT p.projectid, SUM(s.salary) ProjectCost FROM project p
INNER JOIN project_staff ps ON ps.staffid=p.projectid
INNER JOIN staff s ON s.staffid=ps.staffid
GROUP BY p.projectid
) x
GROUP BY x.projectid
每个子查询产生一projectid
列和一ProjectCost
列。单独运行子查询(在括号之间)以查看结果。然后外部查询添加项目的小计。
抱歉,顺便说一句,我在测试时将您的 EquipPrice 和 FishPrice 列重命名为 EPrice 和 FPrice。