我有六个表 - 项目,设备,鱼,员工和联结表 - Project_Equipment,Project_Fish和Project_Staff.I想要检索项目总成本。
所以,我写了如下声明,
SELECT P.ProjectID, (SUM(E.EquipPrice*PE.EQuantity)+SUM(F.FishPrice*PF.FQuantity)+SUM(PS.Salary)) as ProjectCost
FROM Equipment as E INNER JOIN Project_Equipment as PE
ON E.EquipID=PE.EquipID
INNER JOIN Project as P
ON PE.ProjectID=P.ProjectID
INNER JOIN Project_Fish as PF
ON P.ProjectID=PF.ProjectID
INNER JOIN Fish as F
ON PF.FishID=F.FishID
INNER JOIN Project_Staff as PS
ON P.ProjectID=PS.ProjectID
INNER JOIN Staff as S
PS.StaffID=S.StaffID
GROUP BY ProjectID
但是,我得到了两倍正确金额的价格。
答案 0 :(得分:0)
您的查询最终会出现大量重复结果。考虑以下更简单的情况:
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
完全连接这些成本,然后再按{{1}对结果进行分组并总结各个ProjectID
小计。
我解释得很糟糕,但把它想象为设备,鱼和工资成本的小计,然后将所有小计分成一个表并总结那个。 E.g:
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
列。单独运行子查询(在parens之间)以查看结果。外部查询然后添加项目的小计。
抱歉,顺便说一句,我在测试时将您的EquipPrice和FishPrice专栏重命名为EPrice和FPrice。